我需要为Boost.Python定义PyMODINIT_FUNC以暴露C++类吗?

0 投票
1 回答
513 浏览
提问于 2025-04-17 02:36

我在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/

撰写回答