вызвать функцию Cython из C ++ - PullRequest
       337

вызвать функцию Cython из C ++

17 голосов
/ 19 апреля 2011

У меня есть библиотека C ++, в которой есть оболочка Python (написана на SWIG). Эта библиотека позволяет выполнять небольшой определяемый пользователем код (обратный вызов), такой как поэлементные операции с вектором. То есть вместо просто + вы можете сделать любую произвольную двоичную функцию. Прямо сейчас это достигается путем принятия вызываемого объекта Python для двоичной функции и вызова его. Он работает, но примерно в 80 раз медленнее, чем код, который не должен прыгать вверх и вниз в Python на каждой итерации.

Как мне написать / построить / импортировать функцию Cython, которая может быть передана в мою библиотеку C ++, чтобы ее можно было вызывать напрямую из библиотеки C ++?

Edit: Если бы я просто придерживался C, то написал бы что-то вроде

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

EWise тогда callback(10, 20); или что-то подобное. Я хочу, чтобы callback был написан на Cython, используя любое имя, которое хочет пользователь, и указатель на него должен как-то передаваться в мою библиотеку C ++ через Python. Это как-то, где я неясен.

Ответы [ 3 ]

15 голосов
/ 19 апреля 2011

Трюк с Cython заключается в использовании ключевого слова public

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

Затем команда cythonize <your_file.pyx> вместе с <your_file.c> создаст заголовок <your_file.h>, который вы можете включить. Кроме того, вы можете создать заголовок самостоятельно:

#ifdef __cplusplus {
extern "C"
#endif

double cython_function( double value, double value2 );

#ifdef __cplusplus
}
#endif

Обновление

Затем с небольшим оверлеем из Python вы можете использовать механизм обратного вызова ctypes

func_type = CFUNCTYPE(c_double, c_double, c_double)

your_library.set_callback_function ( func_type(user_modules.cython_function) )
2 голосов
/ 20 апреля 2011

Этого можно достичь, выполнив чистые cdef функции:

# 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()

Примечание: вы можете использовать "cython -a", чтобы убедиться, что они не связаны с кодом Python длясодержание бега.Так что он будет работать с вашей библиотекой c.

0 голосов
/ 19 апреля 2011

Встраивание Python в другое приложение может быть полезным чтением.

...