无法从Cython重定向错误流 [英] Can't redirect error stream from Cython

查看:127
本文介绍了无法从Cython重定向错误流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要进行cythonize的SFML库在下面定义了此函数,该函数允许更改将错误打印到的位置(默认情况下,当不调用此函数时,SFML会将错误消息写入控制台):

The SFML library that I'm trying to cythonize defines this function below that allows to change where errors are printed to (by default SFML writes error messages to the console when this function is not called):

namespace sf {
    std::ostream& err() {
        static DefaultErrStreamBuf buffer;
        static std::ostream stream(&buffer);
        return stream;
    }
}

上述功能的简化的.pxd文件:

My simplified .pxd file for the above function:

cdef extern from 'SFML/System.hpp' namespace 'sf':
    ostream& cerr 'sf::err' ()

我的.pyx模块可以编译并正常运行,但不会重定向错误消息(它们仍会打印到控制台上。)。

And my .pyx module, which compiles and runs fine, but doesn't redirect the error messages (they are still printed to the console).

cdef void set_error_handler():
    cerr().rdbuf(NULL)  # This call should prevent errors appearing in the console but it silently fails

set_error_handler()

我正在使用MSVC并与C ++代码静态链接。

I'm using MSVC and linking statically with the C++ code.

编辑

下面是SFML库如何在其自己的代码中记录错误的示例(完整源代码):

Below is example how the SFML library logs errors in its own code (full source):

...
// Error, failed to load the image
err() << "Failed to load image \"" << filename << "\". Reason: " << stbi_failure_reason() << std::endl;
...

我的目标是抑制出现上述错误消息在控制台中,最后将它们重定向到自己的缓冲区中。

My goal is to suppress the error messages like the one above from appearing in the console and eventually later redirect them into own buffer.

推荐答案

有两种解决方法,两种都在您的设置中文件。

There are two ingredients for your problem and both are in your setup-file.

第一个要素是您具有两个扩展名:

The first ingredient is that you have two extensions:

ext_modules = [
    Extension('nebula.sfml.system', ['nebula/sfml/system.pyx'],
              language='c++', ...),
    Extension('nebula.sfml.graphics', ['nebula/sfml/graphics.pyx'],
              language='c++', ...),
] 

这意味着cython将创建两个不同的共享库: system.dll graphics.dll ,稍后都会由python动态加载。

that means cython will create two different shared libraries: system.dll and graphics.dll which will be both loaded later on dynamically by python.

第二个成分: sfml -library是静态链接的,但包含一个单例(q中的错误流uestion),这是灾难的根源:通过您的设置,它不再是单例,而是有两种不同的错误流:来自 system.dll 的错误流。和 graphics.dll 中的一个。因此,您正在从 system.dll 消除错误流(因为您的呼叫 set_error_handler()驻留在此处),但要从 graphics.dll (位于 image_load_test 所在的位置)写入错误流。

The second ingredient: the sfml-library is linked statically but contains a singleton (the error-stream in question) and this is a recipe for disaster: With your set-up it is no longer a singleton, but there are two different error-streams: The one from system.dll and the one from graphics.dll. So you are silencing the error-stream from the system.dll (because your call set_error_handler() lives there), but write to the error-stream from the graphics.dll (this where image_load_test lives).

那该怎么办?有两种选择:

So what can be done? There are two options:


  1. 使用共享的 sfml -库(至少 sfml-system-s ),因此单例将保持为单例。

  2. 将两个pyx文件的内容都放在同一个pyx-文件/扩展名/共享库。至少现在, system.pyx 的内容仅用于 graphics.pyx

  1. Use shared sfml-libraries (at least sfml-system-s), thus the singleton will stay a singleton.
  2. Put the content of both pyx-files in the same pyx-file/Extension/shared library. At least right now, the content of system.pyx is only needed for graphics.pyx.

这篇关于无法从Cython重定向错误流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆