2011-01-04 14 views
10

example.h:Envolver una clase de C++ en Python usando SWIG

#ifndef EXAMPLE_H 
#define EXAMPLE_H 

class Math { 
public: 
    int pi() const; 
    void pi(int pi); 
private: 
    int _pi; 
}; 

#endif 

example.cpp:

#include "example.h" 

int Math::pi() const { 
    return this->_pi; 
} 
void Math::pi(int pi) { 
    this->_pi = pi; 
} 

example.swig:

%module example 
%{ 
    #define SWIG_FILE_WITH_INIT 
    #include "example.h" 
%} 
%include "example.h" 

Yo el n generar los envoltorios, "example.py" y "example_wrap.c" usando:

swig -python example.swig 

Cuando intento compilar la clase contenedora usando:

g++ -fPIC -c example.cpp example_wrap.c -I/usr/local/include/python2.6/ 

me sale el siguiente error:

example_wrap.cpp: In function "PyObject* Swig_var_Math_get()": 
example_wrap.cpp:2725: error: expected primary-expression before "void" 
example_wrap.cpp:2725: error: expected ")" before "void" 

el error es en la línea siguiente:

pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(&Math), SWIGTYPE_p_class, 0); 

#define SWIG_as_voidptr(a) (void *)((const void *)(a)) 

¿Es la manera correcta para generar la clase contenedora "example_wrap.c"?

+0

Tienes problemas de formato bastante malos. –

+1

No es tan malo, simplemente no sabían para sangrar todo el código de cuatro espacios. Fijo. – zwol

Respuesta

5

no hay suficiente información para estar seguro de lo que está mal, pero tengo dos ideas de cosas que puede probar.

  1. Su g++ invocación está compilando un archivo fuente de C como si se tratara de C++. Esta es no se garantiza que funcione. Trate lugar

    gcc -I/usr/local/include/python2.6 -fPIC -c example_wrap.c 
    gcc -I/usr/local/include/python2.6 -fPIC -c example.cpp 
    g++ -shared example_wrap.o example.o -o example.so 
    

    (sí, srsly, use sólo g ++ para el enlace)

  2. Si eso no funciona, compilar example_wrap.c así:

    gcc -I/usr/local/include/python2.6 -fPIC -c -save-temps example_wrap.c 
    

que la voluntad fallar de la misma manera pero producirá un archivo llamado example_wrap.i que es el resultado del preprocesamiento. Será gigantesco Buscar ese archivo para la función Swig_var_Math_get, y añadir a su pregunta el texto completo de esa función (pero nada más).

+0

Vaya, example.cpp se debe compilar con g ++. Por qué gcc? Evitar C++ Mangling? – jweyrich

+1

Solo es necesario usar 'g ++' para vincular. 'gcc -c' hace lo correcto cuando se aplica a un archivo fuente' .cpp'. Pero 'g ++ -c' no * hace * lo correcto cuando se aplica a un archivo fuente' .c'. Entonces, la regla más fácil de recordar es usar siempre 'gcc' para compilar, incluso si la fuente es C++; solo use 'g ++' para vincular un programa que contenga C++. Lo mismo para cualquiera de los otros idiomas admitidos por GCC: use el controlador específico del idioma solo para vincular. Personalmente, no creo que los controladores específicos de idioma siquiera existan, pero sí permiten saber exactamente cómo llamar a las bibliotecas de tiempo de ejecución. – zwol

+0

bueno, sí, puedes usar gcc para compilar C++. También podría usar gcc para vincular C++, pero tendría que vincular manualmente contra libstdC++, etc. Dicho de esa forma, me resulta más fácil usar gcc para C y g ++ para C++. Pero es solo un gusto personal. Lo importante es que el problema y la solución se señalaron correctamente. +1 – jweyrich

13

creo que el comando trago debe ser "trago -C++ -python example.swig"

0

Gracias por su repetición!

la opción -C++ genera la clase C++ para la envoltura. swig -C++ -v -python example.swig

Utilicé g ++ para compilar el contenedor.

g++ -fPIC -c example.cpp example_wrap.cxx -I/usr/local/include/python2.6/ 

Y el siguiente comando para buikd el objeto compartido. Por supuesto, tenemos que eliminar el superflous incluye (-I) y bibliotecas (-L). Los indicadores importantes son '-compartido' y '-fPIC'.

g++ example_wrap.o example.o -L/u01/app/oracle/product/1020.full/lib -I/usr/local/ssl/include -L/usr/local/ssl/lib -lclntsh -lssl -lcrypto -ldl -L/usr/local/lib -L/lib64 -L/usr/local/lib/python2.6/ -lboost_system -lboost_filesystem -lboost_thread -lboost_date_time -lglog -lmodpbase64 -lpthread -ldl -lrt -shared -fPIC -o _example.so 
Cuestiones relacionadas