我需要为Boost.Python定义PyMODINIT_FUNC以暴露C++类吗?
我在Ubuntu上安装了libboost,版本是1.42。
我按照Boost网站上的示例进行了操作:
#include <string>
struct World
{
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
然后创建了idl:
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(hello)
{
class_<World>("World")
.def("greet", &World::greet)
.def("set", &World::set)
;
}
并用bjam构建它:
using python ;
lib libboost_python : : <name>boost_python ;
project
: requirements <library>libboost_python
;
python-extension world : world.cpp ;
但是一旦我导入world,就出现了:
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import world
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initworld)
>>>
我猜它在寻找这样的一个函数:
PyMODINIT_FUNC initworld(void) {
...
}
但是Boost.Python不应该生成这个吗?这个函数是生成了,但找不到吗?还是我需要自己写这个函数?
我知道它确实在尝试导入生成的模块,因为从另一个目录执行时会出现不同的错误。
jsnavely@jsnavely-OptiPlex-980:~/Dropbox/flycap/pytest$ bjam
...found 10 targets...
...updating 5 targets...
MkDir1 bin
MkDir1 bin/gcc-4.5.2
MkDir1 bin/gcc-4.5.2/debug
gcc.compile.c++ bin/gcc-4.5.2/debug/world.o
gcc.link.dll bin/gcc-4.5.2/debug/world.so
...updated 5 targets...
jsnavely@jsnavely-OptiPlex-980:~/Dropbox/flycap/pytest$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import world
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named world
>>>
在正确的目录下:
jsnavely@jsnavely-OptiPlex-980:~/Dropbox/flycap/pytest$ cd bin/gcc-4.5.2/debug/
jsnavely@jsnavely-OptiPlex-980:~/Dropbox/flycap/pytest/bin/gcc-4.5.2/debug$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import world
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initworld)
1 个回答
0
好的,我找到了为什么之前不行的原因。我的C++类放在一个文件里,而IDL放在另一个文件里。因为IDL看起来既不像Python也不像C++,我以为它应该放在不同的文件里。所以IDL的内容根本没有被识别到。
一旦我把所有内容都放到World.cpp这个文件里,一切就都正常运作了!而且运行得非常顺利。
我之所以能搞明白这一点,是因为我查看了“又一个Python GraphViz绑定”这个项目,发现他们的Boost.Python相关代码都放在了和类本身同一个文件里。http://code.google.com/p/yapgvb/