gpt4 book ai didi

python - 无法从 Cython 重定向错误流

转载 作者:太空宇宙 更新时间:2023-11-03 14:57:55 26 4
gpt4 key购买 nike

我尝试 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;
...

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

最佳答案

您的问题有两个因素,并且都在您的设置文件中。

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

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 库是静态链接的,但包含一个单例(有问题的错误流),这是灾难的根源:根据您的设置,它不再是单例,而是有两个不同的错误流:来自 system.dll 的错误流和来自 graphics.dll 的错误流。因此,您将静默来自 system.dll 的错误流(因为您的调用 set_error_handler() 位于此处),但写入来自 graphics.dll 的错误流(这是 image_load_test 所在的位置)。

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

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

关于python - 无法从 Cython 重定向错误流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45361981/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com