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

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

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

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

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

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

3 ответа

Хитрость с 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) )

Вы можете достичь этого, делая чистую 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, используемым для содержимого run. Так что он будет работать с вашей библиотекой c.

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

Другие вопросы по тегам