2011-01-04 17 views
10

example.h:Wrapping una classe C++ in Python utilizzando 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" 

Io il n generare i wrapper, "example.py" e "example_wrap.c" utilizzando:

swig -python example.swig 

Quando provo a compilare la classe wrapper utilizzando:

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

ottengo il seguente errore:

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" 

l'errore è alla seguente riga:

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

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

È il modo giusto per generare la classe wrapper "example_wrap.c"?

+0

Hai problemi di formattazione piuttosto brutti. –

+1

Non male, semplicemente non sapevano riordinare tutti i quattro spazi del codice. Fisso. – zwol

risposta

5

Non ci sono abbastanza informazioni qui per essere sicuri di cosa c'è che non va, ma ho due idee per le cose che puoi provare.

  1. tuo g++ invocazione di compilare un file sorgente C come se fosse C++. Questo è non garantito per funzionare. Prova invece

    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, utilizzare solo g ++ per il link)

  2. Se questo non funziona, compilare example_wrap.c come questo:

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

che verrà fallire allo stesso modo ma produrrà un file chiamato example_wrap.i che è il risultato del pre-processo. Sarà gigantesco. Cerca quel file per la funzione Swig_var_Math_get e aggiungi alla tua domanda il completo del testo di quella funzione (ma nient'altro).

+0

Oops, example.cpp dovrebbe essere compilato con g ++. Perché gcc? Evita la manipolazione C++? – jweyrich

+1

È necessario solo usare 'g ++' per collegare. 'gcc -c' fa la cosa giusta quando viene applicato a un file di origine' .cpp'. Ma 'g ++ -c' fa * not * fa la cosa giusta quando viene applicato a un file sorgente' .c'. Quindi la regola più semplice da ricordare è usare sempre 'gcc' per compilare, anche se l'origine è C++; usa solo 'g ++' per collegare un programma che contiene C++. Stessa cosa per tutte le altre lingue supportate da GCC: utilizzare solo il driver specifico della lingua per il collegamento. Personalmente non penso che i driver specifici della lingua debbano esistere, ma non ti permettono di sapere esattamente come chiamare le librerie di runtime. – zwol

+0

beh, sì, puoi usare gcc per compilare C++. Puoi anche usare gcc per collegare C++, ma dovresti collegarti manualmente a libstdC++, ecc. In questo modo, trovo più facile usare gcc per C e g ++ per C++. Ma è solo un gusto personale. L'importante è che il problema e la soluzione siano stati correttamente segnalati. +1 – jweyrich

13

penso che il comando sorso dovrebbe essere "sorso -C++ -python example.swig"

0

Grazie per la riproduzione!

L'opzione -C++ ha generato la classe C++ per il wrapper. swig -C++ -v -python example.swig

Ho usato g ++ per compilare il wrapper.

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

E il seguente comando per creare l'oggetto condiviso. Ovviamente, abbiamo bisogno di rimuovere il superflous include (-I) e le librerie (-L). Le bandiere importanti sono "-shared" e "-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 
Problemi correlati