2

I would like to be able to use C/C++ functions from python using ctypes python module.

I have a function int doit() in the .c / .cpp file. When I try to load the shared library:

Frr=CDLL("/path/FoCpy2/libFrr.so")
Frr.doit(c_int(5))

i find it working really well when the .c variant is used. When C++ is called the good way to call this function is (found out using nm libFrr.so using nm -gC libFrr.so produces just plain doit()):

Frr._Z4doitv(c_int(5))

I have read on Stackexchange that there is no standard way to call C++ from python, and there is "nonstandard name mangling" issue. Is the "Z4" a part of that issue? I guess the nonstandard name mangling would appear for more advanced language features such as class methods, templates, but also for such basic functions? Is it possible to force using simple C function names in simple cases for the C++ code?

  • 2
    extern "C" { your c API } in your header file... – joy Dec 14 '12 at 22:04
  • you should look into the [swig utility](http://www.swig.org/), specifically the [c++/python support part](http://www.swig.org/Doc1.3/Python.html) – didierc Dec 14 '12 at 22:15

2 Answers2

2

Calling c++ library functions is always a mess, actually even if you're using C++ you have to use the same compiler, etc. to make sure it works.

The only general solution is to define your c++ functions as extern "C" and make sure you follow the involved limitations - see here for an explanation of it.

Community
  • 1
  • 1
Voo
  • 29,040
  • 11
  • 82
  • 156
2

You can use extern "C" to make the functions "look like" C functions to the outside world (i.e., disable name-mangling). And yes, you are correct, name-mangling is needed mostly for the more complicated features and types of functions that C++ has, and the name-mangling scheme has never been standardized (nor the binary compatibility) and so it varies from compiler to compiler and between versions (but most main-stream compilers have settled to something permanent now, but still different between compiler-vendors). And the reason that mangling is also required for plain old free functions is because C++ supports overloading (same function names but with different parameters), and thus, the compilers will encode the parameter specification (e.g., types) into the mangled names. Of course, if you use extern "C" you lose all features for which name-mangling is needed, so, it more or less boils down to C functions only.

You can use extern "C" either on a per-function basis, like so:

extern "C" int doit();

Or for the overall header:

extern "C" {

// all the function declarations here ...

};

However, for Python specifically, I highly recommend that you use a library that allows you to construct Python classes and functions that are a reflection of your C++ classes and functions, that makes life a lot easier and hides away all this extern "C" business. I recommend using Boost.Python, see this getting started page, it makes exporting functions and classes to Python a breeze. I guess others would also recommend SWIG, but I have never used it.

xpda
  • 15,585
  • 8
  • 51
  • 82
Mikael Persson
  • 18,174
  • 6
  • 36
  • 52
  • Thinks for both answers. Boost.Python seems very adequate. Thinks again. –  Dec 15 '12 at 16:21