3

Since I made some progress, I changed the title and made a second edit describing my new problem. You may choose to ignore Edit1

I have been trying to run python code from C code. And for this purpose I have been using Cython.

The semantics of my system is such that there is a binary (whos source I can not access) that calls a C function defined in a file (source is accessible) and within this function I need to call python functions, do some processing and return the result to binary.

To achieve this purpose, there are two approaches that I came across:

  1. http://docs.python.org/release/2.5.2/ext/callingPython.html ===> This approach suggests to have the python callback function passed to the C side, so that the callback is called as necessary, but this doesn't work for me as I don't have access to the binary's source (which is used to run the entire system)

  2. https://stackoverflow.com/a/5721123/1126425 ==> I have tried this approach and I get this error when the cython function is called: Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xb47deb70 (LWP 2065)] 0x007fd38a in PySys_GetObject () from /usr/lib/libpython2.6.so.1.0

  3. http://www.linuxjournal.com/article/8497?page=0,0 ==> This is in fact the basis for cython's functionality but again when I use the examples described there, I get errors similar to 2.

I have no idea how to resolve these errors. Any help would be much appreciated.

Thanks!!

Edit1: here is a simple scenario that reflects situation:


external.c

#include <external.h>

int callback(int param1,int param2)//Function that the binary calls
{
    /*SomeTasks*/
    cython_func();//Function defined in the following .pyx file
    /*SomeTasks*/
}

cython_file.pyx

cdef void cython_function():
    print "Do Nothing!"

I am linking the shared library file created by cython with the library generated by compiling the above C code and then that library is used by the binary...

Edit2: The segmentation fault goes away when I added Py_Initialize(); before calling cython_function(). But now I am getting the undefined symbol error as : symbol lookup error: lib_c_code.so: undefined symbol: cython_function

Here lib_c_code.so is the shared library created out of the external.c file above. I have tried including the .h file created by the cython compiler in external.c but it still didn't work out.. Here is how I am compiling lib_c_code.so:

gcc -shared -dynlib -lm -W1 -o lib_c_code.so $(OBJDIR)/*.o -lc -lm -lpy_code

and the libpy_code.so is the shared object file that was created out of the cython_file.pyx file as:

cython cython_file.pyx -o cython_file.c
gcc $(IFLAGS) -I/usr/include/python2.6 -fPIC -shared cython_file.c -lpython2.6 -lm -o libpy_code.so

Also, I can see the symbol cython_function in the lib_c_code.so file when I do : nm -g lib_c_code.so.. Any ideas please?

Community
  • 1
  • 1
user1126425
  • 2,385
  • 4
  • 18
  • 17

1 Answers1

0

I have to guess here that there's a callback registration function to which you can pass the function pointer, in which case you can simply forego the C file and define a cdef function directly in your Cython code, and pass that with the callback registration function. Use with gil in case you manipulate any Python objects in it.

cdef extern from "external.h":
    ctypedef int (*Cb_Func)(int param1, int param2)
    void register_callback(Cb_Func func)

cdef int my_callback(int param1,int param2) with gil:
    <implementation>

register_callback(my_callback)

This is also explained in the Cython user manual here: http://docs.cython.org/src/userguide/external_C_code.html

kuuko
  • 46
  • 4