Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrapping C++ code with python (manually)

I have a main file(main.cpp) and a header file(nodes.hpp). The main file takes N(any positive integer) as input argument and by using the functions of header file it gives output say 'x & y' (both double).

Note:

  1. Both main and header files are written in C++.
  2. Both main and header files instead of using data structues as arrays,vectors, make use of Eigen Library.

I have to write a python wrapper for them, I have working knowledge of python but have never used any wrapper.

Can anybody please refer or give some notes about using python wrpper for such code?

like image 659
user7440094 Avatar asked Apr 13 '17 08:04

user7440094


People also ask

How do you add a CPP code in Python?

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.

Is C compatible with Python?

Python code can make calls directly into C modules. Those C modules can be either generic C libraries or libraries built specifically to work with Python.

How do I call a Python C++ DLL?

To do this, uncomment the appropriate line at the top of the Python code. Run the Python Script. With the Python script open in the editor, press the F5 button to run it. This will save the Python code, hide the Python Editor window and then execute the Python code which will call the C++ DLL.


2 Answers

Use Boost.Python. Here is my tutorial, previously on SO Docs.


Using Boost.Python

Things are easy when you have to use a C++ library in a Python project. Just you can use Boost.

First of all here is a list of components you need:

  • A CMakeList.txt file, because you're going to use CMake.
  • The C++ files of the C++ project.
  • The python file - this is your python project.

Let's start with a small C++ file. Our C++ project has only one method which returns some string "This is the first try". Call it CppProject.cpp

char const *firstMethod() {
    return "This is the first try.";
}

BOOST_PYTHON_MODULE(CppProject) {
    boost::python::def("getTryString", firstMethod); // boost::python is the namespace
}

Have a CMakeLists.txt file a below:

cmake_minimum_required(VERSION 2.8.3)
FIND_PACKAGE(PythonInterp)
FIND_PACKAGE(PythonLibs)
FIND_PACKAGE(Boost COMPONENTS python)

INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})

PYTHON_ADD_MODULE(NativeLib CppProject)
FILE(COPY MyProject.py DESTINATION .) # See the whole tutorial to understand this line

By this part of the tutorial everything is so easy. you can import the library and call method in your python project. Call your python project MyProject.py.

import NativeLib
print (NativeLib.getTryString)

In order to run your project follow the instructions below:

  • Create a directory with the name build.
  • Enter into that directory.
  • Give the command cmake -DCMAKE_BUILD_TYPE=Release ..
  • make
  • python MyProject.py. Now, you have to see the string which the method in your C++ project returns.
like image 162
Onur Tuna Avatar answered Sep 28 '22 15:09

Onur Tuna


Here are your options:

  1. You can use ctypes, and I consider this the cleanest solution, because you convert your program to a shared library that can be called by any other software, not only Python. You, though, have to write a C-interface for your program yourself.

  2. You can use Python C-Extension, and I consider this the worst solution, because it's very low level, and prone to memory leaks, and costs lots of time to implement one function, and is Python-version dependent. Basically this is good to start a Python interpreter inside your C++. You can create PyObjects (which is the main building block of any Python type) and deal with them insdie C/C++.

  3. You can use SWIG, where it automatically creates the the interface that you have to create with ctypes through an interface file that you define. People say it's very good, but the documentation is not as good.

  4. You can use Boost.Python, which is good, but it has a very ugly build system with bjam. If you can manage to bypass that, then it's even better than ctypes. I'm a big boost fan, but bjam is why I don't use this.

What I do typically is ctypes. I trust it because it emphasizes the single-reponsibility principle. The library has a job that's separate from the interface (the C-interface), which is also separate from your Python script that uses that interface and exposes "the easy functionality" to the user.

like image 23
The Quantum Physicist Avatar answered Sep 28 '22 15:09

The Quantum Physicist