【问题标题】:Can't redirect error stream from Cython无法从 Cython 重定向错误流
【发布时间】:2018-01-03 20:15:11
【问题描述】:

我尝试 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 库如何在其自己的代码 (full source) 中记录错误的示例:

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

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

【问题讨论】:

  • 您能否提供一个最小的 pyx- 文件,您实际在其中使用日志记录?
  • @ead 当然,我已经更新了问题。我没有向sf:err() 记录任何内容,SFML 库会执行此操作,我想抑制它或重定向。
  • 如果你在 c++ 中编写 set_error_handler() 并从 cython 调用它会发生什么。那它行得通吗?只是想排除这不是 sfml 问题。
  • @ead 我可以确认纯 C++ 代码(没有 Cython)成功抑制或重定向错误缓冲区。但我宁愿避免编写 C++,只希望纯 Cython 能工作。

标签: python cython sfml iostream cythonize


【解决方案1】:

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

第一个要素是你有两个扩展:

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

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

第二个成分:sfml-library 是静态链接的,但包含一个单例(有问题的错误流),这是灾难的根源:通过您的设置,它不再是单例,但是是两个不同的错误流:一个来自system.dll,另一个来自graphics.dll。因此,您正在使来自system.dll 的错误流静音(因为您的电话set_error_handler() 在那里),但从graphics.dll 写入错误流(这是image_load_test 所在的位置)。

那么可以做些什么呢?有两种选择:

  1. 使用共享的sfml-libraries(至少sfml-system-s),因此单例将保持为单例。
  2. 将两个 pyx 文件的内容放在同一个 pyx 文件/扩展/共享库中。至少现在,system.pyx 的内容只有graphics.pyx 需要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-14
    • 2015-08-10
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多