It's been a while since my last post but here I am back with a very interesting post about Wrapping C++ libraries to be used in python.
First of all we are going to create a classical client-library program. You can find all the details in my previous post: http://linuxtortures.blogspot.fr/2012/02/shared-libraries-with-eclipse.html
Our library will contain a very simple method "getSomething()" that will return the string "something"
Configure the client project:
Right-click --> Properties
Under C/C++ build, under Settings, under Cross G++ Compiler, under Includes, include the path "${workspace_loc:/Library/src}"
Under C/C++ build, under Settings, under Cross G++ Linker, under Libraries, include the library "Library" and the library search path "${workspace_loc:/Library/Debug}"
Configure the library project (Only if running under 64bits):
Right-click --> Properties
Under C/C++ build, under Settings, under Cross G++ Compiler, under Miscellaneous, select the option "Position Independent Code (-fPIC)"
Compile the code and check that everything is ok, these should be the commands used:
Building file: ../src/Client.cpp
Invoking: Cross G++ Compiler
g++ -I"/home/javier/workspaceSharedLibraries/Library/src" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Client.d" -MT"src/Client.d" -o "src/Client.o" "../src/Client.cpp"
Finished building: ../src/Client.cpp
Building target: Client
Invoking: Cross G++ Linker
g++ -L"/home/javier/workspaceSharedLibraries/Library/Debug" -o "Client" ./src/Client.o -lLibrary
Finished building target: Client
Include the path where is located the compiled Library:
That should be enough to allow running our client:
Now we are going to create our Library wrapper, that will basically allows us to use the Library from python:
First of all, install all the needed dependencies:
sudo apt-get install python-devq
sudo apt-get install libboost-python-dev
Create a new shared library and call it "PythonWrapper":
Important points:
1. Name of the module must match with the name of our library:
BOOST_PYTHON_MODULE(libPythonWrapper)
If you do not follow this advice, you will have issues when importing the library from python:
>>> import libPythonWrapper
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initlibPythonWrapper)
2. Name of the python Class:
class_<Class>("Class")
The name under quotes is how it will looks on python our class, name it the same than in C++ in order to avoid confussion.
3. Name of the python method name:
.def("getSomething", &Class::getSomething)
Same advice, do not invent, and name it the same than our C++ method.
Add the following paths:
And link against the following libraries:
Compile the library, the output should be something like that:
Building file: ../src/PythonWrapper.cpp
Invoking: GCC C++ Compiler
g++ -I"/home/javier/workspaceSharedLibraries/Library/src" -I/usr/include/python2.7 -O0 -g3 -Wall -c -fmessage-length=0 -fPIC -MMD -MP -MF"src/PythonWrapper.d" -MT"src/PythonWrapper.d" -o "src/PythonWrapper.o" "../src/PythonWrapper.cpp"
Finished building: ../src/PythonWrapper.cpp
Building target: libPythonWrapper.so
Invoking: GCC C++ Linker
g++ -L"/home/javier/workspaceSharedLibraries/Library/Debug" -shared -o "libPythonWrapper.so" ./src/PythonWrapper.o -lLibrary -lboost_python -lpython2.7
Finished building target: libPythonWrapper.so
First of all we are going to create a classical client-library program. You can find all the details in my previous post: http://linuxtortures.blogspot.fr/2012/02/shared-libraries-with-eclipse.html
Our library will contain a very simple method "getSomething()" that will return the string "something"
Configure the client project:
Right-click --> Properties
Under C/C++ build, under Settings, under Cross G++ Compiler, under Includes, include the path "${workspace_loc:/Library/src}"
Under C/C++ build, under Settings, under Cross G++ Linker, under Libraries, include the library "Library" and the library search path "${workspace_loc:/Library/Debug}"
Configure the library project (Only if running under 64bits):
Right-click --> Properties
Under C/C++ build, under Settings, under Cross G++ Compiler, under Miscellaneous, select the option "Position Independent Code (-fPIC)"
Compile the code and check that everything is ok, these should be the commands used:
Building file: ../src/Client.cpp
Invoking: Cross G++ Compiler
g++ -I"/home/javier/workspaceSharedLibraries/Library/src" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Client.d" -MT"src/Client.d" -o "src/Client.o" "../src/Client.cpp"
Finished building: ../src/Client.cpp
Building target: Client
Invoking: Cross G++ Linker
g++ -L"/home/javier/workspaceSharedLibraries/Library/Debug" -o "Client" ./src/Client.o -lLibrary
Finished building target: Client
Include the path where is located the compiled Library:
That should be enough to allow running our client:
Now we are going to create our Library wrapper, that will basically allows us to use the Library from python:
First of all, install all the needed dependencies:
sudo apt-get install python-devq
sudo apt-get install libboost-python-dev
Create a new shared library and call it "PythonWrapper":
Important points:
1. Name of the module must match with the name of our library:
BOOST_PYTHON_MODULE(libPythonWrapper)
If you do not follow this advice, you will have issues when importing the library from python:
>>> import libPythonWrapper
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initlibPythonWrapper)
2. Name of the python Class:
class_<Class>("Class")
The name under quotes is how it will looks on python our class, name it the same than in C++ in order to avoid confussion.
3. Name of the python method name:
.def("getSomething", &Class::getSomething)
Same advice, do not invent, and name it the same than our C++ method.
Add the following paths:
And link against the following libraries:
Compile the library, the output should be something like that:
Building file: ../src/PythonWrapper.cpp
Invoking: GCC C++ Compiler
g++ -I"/home/javier/workspaceSharedLibraries/Library/src" -I/usr/include/python2.7 -O0 -g3 -Wall -c -fmessage-length=0 -fPIC -MMD -MP -MF"src/PythonWrapper.d" -MT"src/PythonWrapper.d" -o "src/PythonWrapper.o" "../src/PythonWrapper.cpp"
Finished building: ../src/PythonWrapper.cpp
Building target: libPythonWrapper.so
Invoking: GCC C++ Linker
g++ -L"/home/javier/workspaceSharedLibraries/Library/Debug" -shared -o "libPythonWrapper.so" ./src/PythonWrapper.o -lLibrary -lboost_python -lpython2.7
Finished building target: libPythonWrapper.so
Export the path of our original shared library and import the wrapper from python: