我是否需要为Boost.Python定义PyMODINIT_FUNC来公开C ++类?

时间:2011-09-19 14:07:41

标签: c++ python boost

我通过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 ;

但是一旦我导入世界,我就会得到:

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 :(得分:0)

好吧,我发现了为什么这不起作用。我的C ++类在一个文件中,而我的IDL在另一个文件中。因为它对我来说看起来不像python OR C ++,我认为它属于单独的文件。所以IDL的东西永远不会被拿起来。

一旦我把它放在World.cpp中,一切都按预期工作!也很顺利。

通过查看Yet Another Python GraphViz Binding项目,我发现了这一点,并看到他们所有的Boost.Python东西都被推入与类本身相同的文件中。 http://code.google.com/p/yapgvb/