Así que después de mucho hurgar, probar y error, gritar y arrancarme el pelo, finalmente conseguí que esto funcionara. Sin embargo, primero tuve que volver a escribir mi C++ en C, lo que para mí realmente implicaba la conversión de todas mis variables std::string
al char*
y el seguimiento de algunas longitudes.
Una vez hecho tuve mis archivos .h y .c. Quería hacer una sola función desde el código C disponible en Python. Resulta que Cython puede compilar tus archivos C en la extensión y vincular todas las bibliotecas de una sola vez, comenzando con mi configuración.py, terminó con este aspecto:
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
)
Como se puede ver, el segundo argumento de la extensión se limita a enumerar todos los archivos que necesitan ser compilado, Cython funciona como compilar ellos en función de su extensión de archivo Por lo que yo puedo decir. La matriz de bibliotecas le dice al compilador de Cython a qué se debe vincular (en este caso, estaba envolviendo algunas cosas de criptografía que no podía imitar directamente a través de las libs de Python existentes).
Para hacer realidad mi función C disponible en el archivo .pyx, se escribe un pequeño envoltorio en el .pxd. Mi myext.pxd veía como a continuación:
cdef extern from "../stuff.h":
char* myfunc(char* arg1, char* arg2, char* arg3)
En el .pyx a continuación, utiliza la declaración cimport importar esta función, que está entonces disponible para su uso como si se tratara de cualquier otra función de Python:
cimport myext
def my_python_func(arg1, arg2, arg3):
result = myext.myfunc(arg1, arg2, arg3)
return result
Cuando construyes esto (al menos en Mac) obtienes un .so que puedes importar en python y ejecutar las funciones desde el .pyx. Puede haber una forma mejor y más correcta de hacer que todo funcione, pero eso viene de la experiencia y este fue el primer encuentro que logré resolver. Me interesarían mucho los punteros en los que podría haberme equivocado.
Actualización:
Después de seguir utilizando Cython, encontré que era muy fácil de integrar con C++ también, una vez que sabes lo que estás haciendo. Hacer disponible en C++ string
es tan simple como from libcpp.string cimport string
en su pyx/pyd. La declaración de la clase C++ es tan fácil como:
cdef extern from "MyCPPClass.h":
cdef cppclass MyCPPClass:
int foo;
string bar;
Claro que tiene que redeclare básicamente la definición .h de la clase en un formato Pythonic, pero eso es un pequeño precio a pagar por tener acceso a las funciones que ya se han escrito en C++ .
Si su pregunta ha sido respondida, por favor marque esta pregunta como respondida. De lo contrario, por favor especifique su pregunta una vez más. –
@NiklasR Tu respuesta cubrió algunas de mis áreas de confusión pero no me ayudó a llegar al final. Le di un voto positivo, pero tenía la intención de escribir una respuesta completa de los otros aspectos que resolví cuando tengo tiempo libre. – Endophage