Итак, после множества попыток, проб и ошибок, криков и рвущихся волос я наконец-то начал работать.Сначала я должен был переписать свой C ++ в C, что для меня на самом деле было просто преобразованием всех моих std::string
переменных в char*
и отслеживанием некоторых длин.
Как только я закончил, у меня был свой.файлы h и .cЯ хотел сделать единственную функцию из кода C доступной в Python.Оказывается, что Cython может скомпилировать ваши C-файлы в расширение для вас и связать любые библиотеки за один раз, поэтому, начиная с моего setup.py, он в итоге выглядел так:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules=[
Extension("myext",
["myext.pyx", "../stuff.c"],
libraries=["ssl", "crypto"]
)
]
setup(
name = "myext",
cmdclass = {"build_ext": build_ext},
ext_modules = ext_modules
)
По мере того как выКак видите, второй аргумент в расширении просто перечисляет все файлы, которые должны быть скомпилированы, Cython решает, как их скомпилировать в зависимости от их расширения, насколько я могу судить.Массив library сообщает компилятору Cython, что нужно связать (в этом случае я оборачивал некоторые криптографические материалы, которые я не могу имитировать непосредственно через существующие библиотеки Python).
Чтобы фактически сделать мою функцию Cдоступны в .pyx файле, вы пишете небольшую оболочку в .pxd.Мой myext.pxd выглядел следующим образом:
cdef extern from "../stuff.h":
char* myfunc(char* arg1, char* arg2, char* arg3)
В .pyx вы затем используете объявление cimport для импорта этой функции, которая затем доступна для использования, как если бы это была любая другая функция Python:
cimport myext
def my_python_func(arg1, arg2, arg3):
result = myext.myfunc(arg1, arg2, arg3)
return result
Когда вы создаете это (по крайней мере, на Mac), вы получаете .so, который вы можете импортировать в python и запускать функции из .pyx.Возможно, есть лучший, более правильный способ заставить все это работать, но это происходит из опыта, и это была первая встреча, которую мне удалось выработать.Я был бы очень заинтересован в указателях, где я мог ошибиться.
Обновление:
После дальнейшего использования Cython я обнаружил, что его было очень просто интегрироватьс C ++, когда вы знаете, что делаете.Сделать доступным для C ++ string
так же просто, как from libcpp.string cimport string
в вашем pyx / pyd.Объявление класса C ++ так же просто, как:
cdef extern from "MyCPPClass.h":
cdef cppclass MyCPPClass:
int foo;
string bar;
Конечно, вам нужно переопределить определение .h вашего класса в формате Pythonic, но это небольшая цена за получение доступа к уже написанному.Функции C ++.