我最近在使用几个已编译的 C++ 模块时发现了一个问题,并想重新表述这个问题。
我有两个模块“mod1”和“mod2”。它们在我的 setup.py 中编译为两个不同的“ext_modules”,如下所示:
#!/usr/bin/python2
from setuptools import setup, Extension
mod1 = Extension('mod1',
sources = ['mod1.cpp'],
libraries = ['boost_python'])
mod2 = Extension('mod2',
sources = ['mod2.cpp'],
libraries = ['boost_python'])
setup(name='foo',
version='0.0',
description='',
ext_modules=[mod1,mod2],
install_requires=['distribute'])
但在内部,“mod2.hpp”包含“mod1.hpp”,因为第一个模块定义了第二个模块使用的东西。
编辑:这将编译得很好,但是:
$> cd build/lib.linux-i686-2.7
$> python2 -c "import mod1 ; import mod2"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: ./mod2.so: undefined symbol: _ZN6ParentD2Ev
这里,“Parent”是在 mod1 中定义并在 mod2 中使用的类的名称。
EDIT2:另一个我不明白的奇怪行为:
$> cd build/lib.linux-i686-2.7
$> python2
Python 2.7.2 (default, Nov 21 2011, 17:24:32)
[GCC 4.6.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mod2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: ./mod2.so: undefined symbol: _ZN6ParentD2Ev
>>> import mod1
>>> import mod2
Segmentation fault
在这里,首先导入 mod2 失败。但是如果我在导入 mod1 后尝试 agin,我会得到一个段错误。
这两个模块都是作为共享库构建的——但如果我没记错的话,mod2 需要链接到 mod1 才能工作,因为它需要在 mod1 中定义的东西。是否可以使用 setuptools/distribute 定义这样的依赖关系?
就像是 :
mod2 = Extension('mod2',
sources = ['mod2.cpp'],
libraries = ['boost_python',mod1])
从我的各种阅读来看,似乎可以使用 boost 的 bjam 实用程序来做这样的事情——不幸的是,我没有设法在我的系统上使用它(甚至编译示例)。
我尝试过的事情:
- 将“mod1.cpp”添加到 mod2 的源代码中。它可以工作(有点:我必须在 mod2 之前导入 mod1 才能使其工作)但我失去了将模块作为共享对象的兴趣。
解决方法:
- 将 mod1 作为 mod2 中的常规 python 模块导入,但这会在我的 C++ 代码中添加额外的 python 层
你怎么看 ?