do I need to define an PyMODINIT_FUNC for Boost.Python to expose a C++ class?
I have libboost installed via Ubuntu. The boost version is 1.42. I've followed the example on the Boost website:
#include <string>
struct World
{
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
then created the idl:
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(hello)
{
class_<World>("World")
.def("greet", &World::greet)
.def("set", &World::set)
;
}
and build it with bjam:
using python ;
lib libboost_python : : <name>boost_python ;
project
: requirements <library>libboost_python
;
python-extension world : world.cpp ;
But as soon as I import world, I get:
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)
>>>
I'm guessing its looking for a function like this:
PyMODINIT_FUNC initworld(void) {
...
}
But I isn't Boost.Python supposed create this? Is the function being generated, but just not found? Or do I need to write it myself?
I know its really attempting to import the generated module, because it gi开发者_如何学Pythonves a different error when executing from another directory.
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
>>>
In the correct directory:
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)
ok, I found out why this wasn't working. My C++ class was in one file, and my IDL was in another. Because it didn't look like python OR C++ to me, I thought it belonged in separate file. So the IDL stuff was never getting picked up.
Once I put it all together in World.cpp, everything worked as expected! Very smoothly, too.
I figured this out by looking at the Yet Another Python GraphViz Binding project, and saw that all their Boost.Python stuff was shoved into the same file as the class itself. http://code.google.com/p/yapgvb/
精彩评论