Import python C++ modules

Asked

Viewed 1,155 times

3

I’m trying to import into one script python a module C++:

import hector_path_follower

The archive c++ defines a namespace for the class:

namespace pose_follower {
 class HectorPathFollower
 { 
   ...
 }
}

In my python script the import is correctly interpreted, but when trying to access a method the namespace is not recognized.

pf = pose_follower.HectorPathFollower()

I’m using pycharm community Edition 2017.3.3

  • So I’ve even played a C pseudo module for Python on Linux. I don’t remember exactly what I did to make it work, but I think one of the important things to use C was the fact that C’s ABI is stable and standardized, whereas C++ depends on the compiler (and maybe the linker, I’m not sure). To indicate that you want to use C ABI in C++, there is the directive extern "C". That was something I needed to take into consideration, but it’s been a while. I can’t think of any other details

  • @Jeffersonquesado the case of "extern" does not apply my claim, since I have everything properly defined. What I want is to import them and use the python code

1 answer

4


Modules in other languages are not directly usable from Python.

The fact that the module is imported is why Python can import modules .so on Unix or .dll in Windows - but these modules have to have specific structures inside so that Python elements are visible in the language. For this it is necessary to place some data structures and call a specific record defined in Cpython-API - And of all that I describe below, it is the method that gives the most work. Although, as it is pure C, for those who are accustomed, it will not involve learning or using any other intermediate language or configuration technology.

It is possible to read directly the .so and call the extern functions inside, but for that it is necessary to use the "ctypes" Python, and redefen, on the Python side, the functions you want to use and the structs used by them. C++ has an additional complication with the function name scheme, but it would also work.

Usually people use the tool "swig" or the framework "boost": they allow, with just a little configuration, the automatic generation of Python links from native libraries in C++ - if what you want to use in C++ is ready and complete, I would recommend using one of these two - but you’ll have to check the documentation. After the Python module generated by these tools, just really use from Python what you have in C++.

Another tool is still the Cython - it is a Python superconcombination compiled for native code - but it will also depend on defining functions and structs in its own syntax more or less manually before they are used (and I don’t know how Cython works for classes in C++ - I suppose there is a way).

And finally, there’s the cffi which also allows pure Python code to make calls to native code.

By comparing roughly the following: To Cpython API is the "official" way to link to native code, used internally in the cPython project itself. It requires that every method, function or data structure that is visible and searchable from Python be written manually - within these methods you make the calls to read the parameters passed and convert the data types to those used internally in your C++ code (for example, convert an object int from Python to a C++ int64) - call your function, and check the return values back on Python objects. You also need to list all these functions in specific Structs for your record, so that they are visible from Python. It is really quite laborious. I believe that in this way it is even possible to have a single file. only and or . dll that works directly for C and C++ and also for Python. All of the ways below will generate a secondary file for this.

ctypes allows you to write all the extra code to use the libraries in C++ in pure Python as part of your Python program, and does not require any other statement - but there is a certain impedance until you understand the mechanics of ctypes, and the problem of having to define the equivalent of function prototypes and structs manually. Ctypes is very practical when you are writing code in pure Python and want to call only some functions of some library that does not have the adapter for Python it allows you to without installing any dependency, nor change language, you write the direct calls in Python.

The cffi - is almost the same thing as ctypes. It has tools to directly read the .h - but cffi does not follow Python, and requires a separate library installation from Pypi.

The option of Cython, in my opinion, it makes more sense when someone who is not the author of the original library in C or C++ wants to leave the module compiled in Python ready for third party use - as you have everything in hand there, I guess that’s not the case. As written above, it depends on writing a specific adaptor code.

Swig and Boost work better with intervention in the C++ package, or at least depend on having the .h and .hpp available - but once configured correctly, the intermediate module for Python is generated and can be installed directly with the binaries that C++ generates; for third parties who will program in Python and make use of their C++ code, these two may be the best option. I never used enough of them to know which one is better. I think Swig is simpler. Even he has understand the namespaces - see section 36.3.12 at http://www.swig.org/Doc3.0/SWIGDocumentation.html#Python_nn2

I think it’s worth taking a look at Swig first. If it’s complicated for C++, look at Boost, which is native to C++ - if you still have difficulties, then evaluate the others.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.