So I'm trying to interface python 3.2 and c++ using boost python, and have come across many many issues. I've finally gotten it to compile using the 2.7 libraries and it works, but I can't seem to make it work with python 3.2.
Here's the c++ code
#include <iostream>
using namespace std;
void say_hello(const char* name) {
cout << "Hello " << name << "!\n";
}
int main(){return 0;}
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(hello)
{
def("say_hello", say_hello);
}
If I compile it using the 2.7 libraries it works just fine, but when I use the 3.2 libraries I get tons of undefined references from libboost_python.so
Otherwise I wrote a little bit of python to make it work:
from distutils.core import setup
from distutils.extension import Extension
setup(name="PackageName",
ext_modules=[
Extension("hello", ["testBoost.cpp"],
libraries = ["boost_python"])
])
and this will create an so using python 3.2 or 2.7 build, but when I open the python 3 interpreter and attempt to import the so it give me the error undefined symbol PyClass_Type from libboost_python.so again. Any ideas? Is boost python compatible with python 3.x?
If the information is useful, here is my attempted compile using 3.2:
$ g++ testBoost.cpp -I/usr/include/python3.2 -I/usr/local/include/boost/python -lboost_python -lpython3.2mu
/tmp/ccdmU1Yu.o: In function `PyInit_hello':
testBoost.cpp:(.text+0xc2): undefined reference to `boost::python::detail::init_module(PyModuleDef&, void (*)())'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_Size'
/usr/local/lib/libboost_python.so: undefined reference to `PyFile_FromString'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_Type'
/usr/local/lib/libboost_python.so: undefined reference to `PyInt_Type'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_FromString'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_FromStringAndSize'
/usr/local/lib/libboost_python.so: undefined reference to `Py_InitModule4_64'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_FromFormat'
/usr/local/lib/libboost_python.so: undefined reference to `PyNumber_Divide'
/usr/local/lib/libboost_python.so: undefined reference to `PyNumber_InPlaceDivide'
/usr/local/lib/libboost_python.so: undefined reference to `PyInt_AsLong'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_InternFromString'
/usr/local/lib/libboost_python.so: undefined reference to `PyClass_Type'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_AsString'
/usr/local/lib/libboost_python.so: undefined reference to `PyInt_FromLong'
/usr/local/lib/libboost_python.so: undefined reference to `PyFile_AsFile'
collect2: ld returned 1 exit status
And the error from the python 3 interpreter is
File "<stdin>", line 1, in <module>
ImportError: /usr/local/lib/libboost_python.so.1.47.0: undefined symbol: PyClass_Type
Thanks for any help!
The way to use Python V3 with Boost is to properly configure the build system by adding for instance: using python : 3.1 : /your_python31_root ; to your user-config. jam file.
The Boost Python Library is a framework for interfacing Python and C++. It allows you to quickly and seamlessly expose C++ classes functions and objects to Python, and vice-versa, using no special tools -- just your C++ compiler.
Linking in the python libraries (for e.g. -L/usr/lib/x86_64-linux-gnu -lpython2.7 on linux or find_package(PythonLibs) in CMake1) will make this linker issue go away.
Here is a more detailed explanation of the issue below. On the command line,
$ nm --dynamic <path-to>/libboost_python.so | grep PyString_Size
If you are feeling lazy and assuming your libboost_python is linking to python2.7, just run this
$ nm --dynamic `locate libboost_python27.so | awk 'NR==1'` | grep PyString_Size
You should see something like
U PyString_Size
So PyString_Size is undefined (U
) in libboost_python27.so. This is what the linker was complaining about. We've confirmed that. Now let's look for this symbol in libpython.
$ nm --dynamic `locate libpython2.7.so | awk 'NR==1'` | grep PyString_Size
On my machine, I saw something like this:
00000000000f0530 T PyString_Size
The T
indicates that the text for this symbol is at the address indicated. So this is proof that we were not linking in libpython in addition to libboost_python.
1 Why aren't you using CMake? :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With