不能从Cython中重定向错误流[英] Can't redirect error stream from Cython

本文是小编为大家收集整理的关于不能从Cython中重定向错误流的处理方法,想解了不能从Cython中重定向错误流的问题怎么解决?不能从Cython中重定向错误流问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我试图cythonize的SFML库在下面定义了此功能,该功能允许在将错误打印到的地方更改(默认情况下,当未调用此函数时,SFML将错误消息写入控制台):

):

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

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

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

和我的.pyx模块,该模块编译并运行正常,但没有重定向错误消息(它们仍打印到控制台).

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 ++代码静态链接.

编辑

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

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

我的目标是抑制像上面出现在控制台中的错误消息,并最终将其重定向到自己的缓冲区中.

推荐答案

您的问题有两种成分,两者都在您的设置文件中.

第一种成分是您有两个扩展:

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动态加载.

第二个成分:sfml library在静态上链接,但包含一个单例(有问题的错误流),这是灾难的秘诀:使用您的设置,它不再是单身人士,但是那里是两个不同的误差流:system.dll的一个和graphics.dll的一个.因此,您是在沉默system.dll中的错误流(因为您的调用set_error_handler()住在那里),但要写入graphics.dll的错误流(此处image_load_test live).

那么怎么办?有两个选择:

  1. 使用共享sfml -Libraries(至少sfml-system-s),因此单身人士将保持单身人士.
  2. 将两个pyx文件的内容放在同一pyx文件/扩展/共享库中.至少现在,system.pyx的内容仅对于graphics.pyx.

本文地址:https://www.itbaoku.cn/post/1793843.html