Skip to content
Advertisement

Segmentation fault when calling a more complex C++ function from Python with ctypes [closed]

I have a function in C++ code which I want to call from Python with ctypes. The shared library (libRunaphys.so, I’m on Linux) contains a lot of other functions but I only need to use one function. The function is called advance_runaway_population() and it is not part of any class. I wrote the following after the function descritptions in

control.cpp

JavaScript

where plasma_local and module_struct are both custom structures and rate_values is an array of 4 doubles. My header file looks like

control.h

JavaScript

I wrote a Python script in which I want to test the C++ function:

python_constructor.py

JavaScript

I managed to make structures from Python, though I’m not sure wheter they are suitable for C++ as well. Also I found another question regarding passing strings and I made my MODULE struct accordingly.

The Python code runs fine until the C++ function call, where it exits with Segmentation fault. I’ve been searching and I found that my problem is most likely with the passing of pointers between Python and C++. Since my C++ function requires pretty specific structures and isn’t part of a class I couldn’t find a tutorial to use. I was reading the ctypes documentation too but I couldn’t apply those examples to my usecase either. I primarily work in Python so I’m not too familiar with C++, C and ctypes so please point out the trivial mistakes too.

How can I pass pointers to C structures (made in Python) from Python to C++?

If possible I would like to use ctypes because the code should be as portable as possible, but if there is a much simpler way for me to be able to call this C++ function I am open to that solution as well.

Advertisement

Answer

Here’s a working example. the module_struct std::string values can’t be generated in Python, so a wrapper structure with C types is used to pass from Python to C, and the extern "C" function takes that wrapper class instance and converts it to a proper C++ class instance.

Also you don’t have to wrap every parameter in a ctypes type. ctypes “knows” the wrapper type if .argtypes are declared correctly.

for passing rate_values, ct.byref(rate_values) is equivalent to double(*)[4] type. Don’t use ct.byref and the c_double * 4 array will be passed as ct.POINTER(double). this is similar to a C array decaying to a pointer as a parameter.

control.cpp:

JavaScript

test.py

JavaScript

Output:

JavaScript
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement