raspberry pyx pyrex python cython

pyx - pyrex python



Envuelva C++ lib con Cython (3)

Creo que puede solucionar este problema específico especificando los library_dirs correctos (donde realmente colocó libtest.a - aparentemente no se encuentra), pero creo que tendrá otro problema: sus puntos de entrada no se declaran correctamente. extern "C" , por lo que los nombres de las funciones habrán sido "destrozados" por el compilador de C ++ (mira los nombres exportados desde libtest.a y verás!), por lo que cualquier otro idioma, excepto C ++ (incluido C, Cython, etc) tendrán problemas para llegar a ellos. La solución es declararlos como extern "C" .

Soy nuevo en Cython y estoy tratando de usar Cython para envolver una biblioteca estática C / C ++. Hice un ejemplo simple como el siguiente.

Prueba.h:

#ifndef TEST_H #define TEST_H int add(int a, int b); int multipy(int a, int b); #endif

Test.cpp

#include "test.h" int add(int a, int b) { return a+b; } int multipy(int a, int b) { return a*b; }

Luego usé g ++ para compilarlo y construirlo.

g++ -c test.cpp -o libtest.o ar rcs libtest.a libtest.o

Así que ahora tengo una biblioteca estática llamada libtest.a.

Test.pyx:

cdef extern from "test.h": int add(int a,int b) int multipy(int a,int b) print add(2,3)

Setup.py:

from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext ext_modules = [Extension("test", ["test.pyx"], language=''c++'', include_dirs=[r''.''], library_dirs=[r''.''], libraries=[''libtest''] )] setup( name = ''test'', cmdclass = {''build_ext'': build_ext}, ext_modules = ext_modules )

El llamé:

python setup.py build_ext --compiler=mingw32 --inplace

La salida fue:

running build_ext cythoning test.pyx to test.cpp building ''test'' extension creating build creating build/temp.win32-2.6 creating build/temp.win32-2.6/Release C:/Program Files/pythonxy/mingw/bin/gcc.exe -mno-cygwin -mdll -O -Wall -I. -IC:/ Python26/include -IC:/Python26/PC -c test.cpp -o build/temp.win32-2.6/Release/test.o writing build/temp.win32-2.6/Release/test.def C:/Program Files/pythonxy/mingw/bin/g++.exe -mno-cygwin -mdll -static --entry _D llMain@12 --output-lib build/temp.win32-2.6/Release/libtest.a --def build/temp.w in32-2.6/Release/test.def -s build/temp.win32-2.6/Release/test.o -L. -LC:/Python 26/libs -LC:/Python26/PCbuild -ltest -lpython26 -lmsvcr90 -o test.pyd g++: build/temp.win32-2.6/Release/libtest.a: No such file or directory error: command ''g++'' failed with exit status 1

También intenté usar las bibliotecas = [''prueba''] en lugar de las bibliotecas = [''libtest'']. Me dio los mismos errores.

¿Alguna pista sobre eso?

¡Gracias!


Si su código de C ++ solo lo utiliza el envoltorio, otra opción es permitir que la configuración compile su archivo .cpp, como este:

from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext ext_modules = [Extension("test", ["test.pyx", "test.cpp"], language=''c++'', )] setup( name = ''test'', cmdclass = {''build_ext'': build_ext}, ext_modules = ext_modules )

Para enlazar a una biblioteca estática, debe usar el argumento extra_objects en su Extension :

from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext ext_modules = [Extension("test", ["test.pyx"], language=''c++'', extra_objects=["libtest.a"], )] setup( name = ''test'', cmdclass = {''build_ext'': build_ext}, ext_modules = ext_modules )


Tu archivo Test.pyx no está haciendo lo que esperas. La línea de print add(2,3) no llamará a la función add() C ++; tienes que crear explícitamente una función de envoltura para hacer eso. Cython no crea envoltorios para ti automáticamente.

Algo como esto es probablemente lo que quieres:

cdef extern from "test.h": int _add "add"(int a,int b) int _multiply "multiply"(int a,int b) def add(a, b): return _add(a, b) def multiply(a, b): return _multiply(a, b) print add(2, 3)

Puedes consultar la documentation de Cython para más detalles.