Llamar al código C ++ desde Python usando Cython con el enfoque distutilis

Estoy intentando llamar a un código c ++ desde un script de python usando cython. Ya me las arreglé para trabajar con un ejemplo desde aquí, pero la cosa es: mi código c ++ incluye bibliotecas no estándar de opencv. Creo que no los estoy vinculando correctamente, así que necesito que alguien vea mis archivos setup.py y cpp_rect.h y cpp_rect.cpp .

El error que recibo se refiere a la línea en negrita yn al archivo * .cpp: cv :: Mat img1 (7,7, CV_32FC2, Scalar (1,3)); Cuando bash probar la biblioteca, recibo un error de inclusión al ejecutar $ python userect.py :

 Traceback (most recent call last): File "userect.py", line 2, in  from rectangle import Rectangle ImportError: dlopen(/Users/marcelosalloum/Desktop/python_cpp_interface/rectangle.so, 2): Symbol not found: __ZN2cv3Mat10deallocateEv Referenced from: /Users/marcelosalloum/Desktop/python_cpp_interface/rectangle.so Expected in: flat namespace in /Users/marcelosalloum/Desktop/python_cpp_interface/rectangle.so 

El símbolo no encontrado (__ZN2cv3Mat10deallocateEv) tiene algo que ver con la función cv::Mat::deallocate() , lo que indica que mis importaciones no funcionan correctamente.

¿Algunas ideas?


Mis otras clases son las siguientes:

Este es mi archivo setup.py Tenga en cuenta que ya incluí 2 directorios, aunque no estoy seguro de si lo hice correctamente:

 from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext setup( name = 'Demos', ext_modules=[ Extension("rectangle", sources=["rectangle.pyx", "cpp_rect.cpp"], # Note, you can link against a c++ library instead of including the source include_dirs=[".", "/usr/local/include/opencv/", "/usr/local/include/"], language="c++"), ], cmdclass = {'build_ext': build_ext}, ) 

Mi archivo cpp_rect.h incluye un cv.h y un espacio de nombres cv, como se muestra a continuación:

 #include "source/AntiShake.h" #include  #include "cv.h" using namespace cv; class Rectangle { public: int x0, y0, x1, y1; Rectangle(); Rectangle(int x0, int y0, int x1, int y1); ~Rectangle(); int getLength(); int getHeight(); int getArea(); void move(int dx, int dy); **void openCV();** Rectangle operator+(const Rectangle& other); }; 

y mi función openCV () simplemente crea una instancia de cv :: Mat desde opencv (archivo cpp_rect.cpp ):

 #include "cpp_rect.h" Rectangle::Rectangle() { x0 = y0 = x1 = y1 = 0; } Rectangle::Rectangle(int a, int b, int c, int d) { x0 = a; y0 = b; x1 = c; y1 = d; } Rectangle::~Rectangle() { } void Rectangle::openCV(){ **cv::Mat img1(7,7,CV_32FC2,Scalar(1,3));** } ... 

Puedo comstackr el archivo con el siguiente comando: $ python setup.py build_ext --inplace , que me proporciona el archivo * .so. Pero cuando ejecuto mi script userect.py, recibo ese error de inclusión descrito primero en esta pregunta.

¿Algunas ideas?

Resuelto, gracias a los comentarios de Dietmar Kühl y este video de youtube !

¿Que está mal? Descubrí que mi setup.py estaba mal configurado. Debería ser como

 from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext setup( name = 'DyCppInterface', version = '1.0', author = 'Marcelo Salloum dos Santos', # The ext modules interface the cpp code with the python one: ext_modules=[ Extension("rectangle", sources=["rectangle.pyx", "cpp_rect.cpp"], # Note, you can link against a c++ library instead of including the source include_dirs=[".","source" , "/opt/local/include/opencv", "/opt/local/include"], language="c++", library_dirs=['/opt/local/lib', 'source'], libraries=['opencv_core', 'LibCppOpenCV']) ], cmdclass = {'build_ext': build_ext}, ) 

Las tres cosas a las que hay que prestar atención para configurarlo correctamente son:

  • include_dirs : cada archivo referenciado en setup.py o .h y .cpp tendrá su carpeta contenedora en include_dirs;
  • library_dirs : cada biblioteca referenciada tendrá su carpeta contenedora escrita aquí;
  • bibliotecas : una DEBE poner el nombre de la biblioteca aquí

Se pueden responder otras preguntas sobre cómo configurar una biblioteca para cython viendo este video sobre cómo usar y configurar una biblioteca dinámica (usando Eclipse CDT) .