开发者

call Cython function from C++

开发者 https://www.devze.com 2023-02-26 07:44 出处:网络
I have a C++ library that has a Python wrapper (written with SWIG). This library allows executing small user-defined code (a callback), such as element-wise operations on a vector. I.e. instead of jus

I have a C++ library that has a Python wrapper (written with SWIG). This library allows executing small user-defined code (a callback), such as element-wise operations on a vector. I.e. instead of just a + you can do whatever arbitrary binary function. Ri开发者_开发问答ght now this is accomplished by accepting a callable Python object for the binary function and calling it. It works, but is about 80 times slower than code that doesn't have to bounce up and down into Python at every iteration.

How would I write/build/import a Cython function could be passed into my C++ library so that it can be called directly by the C++ library?

Edit: If I just stuck to C then I would write something like

EWise(double (*callback)(double, double))

EWise would then callback(10, 20); or such. I want callback to be written in Cython, using whatever name the user wants, and a pointer to it has to be passed to my C++ library through Python somehow. That somehow is where I'm unclear.


The trick with cython is in using the keyword public

cdef public double cython_function( double value, double value2 ):
    return value + value2

Then the command cythonize <your_file.pyx> along with <your_file.c> will create header <your_file.h> that you can include. Alternatively, you can create the header yourself:

#ifdef __cplusplus {
extern "C"
#endif

double cython_function( double value, double value2 );

#ifdef __cplusplus
}
#endif

Update:

Then with a little overlay from Python you can use ctypes's callback mechanism

func_type = CFUNCTYPE(c_double, c_double, c_double)

your_library.set_callback_function ( func_type(user_modules.cython_function) )


You can achieve that by doing pure cdef functions :

# declare the prototype of your function
ctypedef void (*callback_ptr)(int arg)

# declare your function as cdef
cdef void my_callback(int arg):
    print 'doing some python here', arg

# now, you can use the cdef func as a callback
# in pure C !
cdef void run():
    cdef callback_ptr p = my_callback
    p(42)

if __name__ == '__main__':
    run()

Note: you can use "cython -a" to see that they are no python code involved for the content of run. So it will work with your c library.


Embedding Python in Another Application may be useful reading.

0

精彩评论

暂无评论...
验证码 换一张
取 消