当我尝试将 c++ 共享库导入到 python 2.5 的 Windows 版本时,Python 正在“挂起”,我不知道为什么。
在 Linux 上,一切正常。我们可以编译我们所有的 C++ 代码,生成 swig 包装类。它们可以编译并且可以在 python 2.5 或 2.6 中导入和使用。现在,我们正在尝试使用 Cygwin 将代码移植到 Windows。
我们能够使用 -mno-cygwin 将每个 C++ 库编译为共享 dll,这消除了对 cygwin1.dll 的依赖。从本质上讲,这会导致 gcc 目标是 MinGW 而不是 Cygwin,从而使生成的二进制文件能够在 Windows 中运行而不依赖于 Cygwin。此外,这些共享库中的每一个都可以链接到 c++ 二进制文件并成功运行。
完成此操作后,我们使用 swig 为每个共享库生成包装器。这些包装器可以毫无问题地生成、编译和链接。
然后,下一步是将生成的 python 包装器导入 python。我们能够导入除两个库之外的所有库。对于这两个不起作用,当我们尝试将 .py 或 .pyd 文件导入 Windows python(使用 Visual C++ 编译的版本)时,python 挂起。我们不能用 ctrl+c 或 ctrl+d 杀死 python,唯一的办法是通过任务管理器杀死它。如果我们将 gdb 附加到 python 进程并打印堆栈跟踪,我们大多会得到垃圾,没有任何用处。
接下来,我们尝试使用 ifdef 将 *.i 文件中的代码块取出并重新创建 swig 包装器。这个过程至少允许我将库导入 Windows python,但问题是我们必须注释掉太多软件运行所必需的函数。通常,必须注释掉三种类型的函数:静态函数、虚拟 const 函数和未声明为 const 的常规公共函数。这也是可重现的,如果我们取消注释这些函数中的任何一个,那么导入会再次挂起。
接下来,我们尝试将函数提取到一个简单的 hello world 程序中,生成一个 swig 包装器并将它们导入 python。这行得通。我们完全从头文件中复制了函数。它们在非常小的测试程序中工作,而不是在更大的共享库中。我们以完全相同的方式构建它们。
因此,任何关于为什么会发生这种情况的想法,甚至只是更好的调试技术都会非常有帮助。
这些在使用 gcc 3 和 4 以及 python 2.5 和 2.6 的 Linux 上运行良好。在 Windows 上,这是我正在使用的软件:gcc 3.4.4 swig 1.39(来自 swig.org 的 Windows 二进制文件)python 2.5.4(来自 python.org 的 Windows 二进制文件和包含/库)
这些是我用于构建简单的 hello world 程序的命令(完整的库使用相同的选项,只是因为额外的 -I、-L 和 -l 选项而更长)
痛饮 -c++ -python -o test_wrap.cc test.i
gcc -c -mno-cygwin test.cc
gcc -c -mno-cygwin test_wrap.cc -I/usr/python25/include
dlltool --export-all --output-def _test.def test.o
gcc -mno-cygwin -shared -s test_wrap.o test.o -L/usr/python25/libs -lpython25 -lstdc++ -o _TestModule.pyd
谢谢, AJ