2011-01-04 2 views
10

example.h:eine C++ Klasse in Python Wrapping SWIG Verwendung

#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" 

Ich der n erzeugen die Wrapper "example.py" und "example_wrap.c" mit:

swig -python example.swig 

Wenn ich versuche, mit der Wrapper-Klasse zu kompilieren:

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

ich die folgende Fehlermeldung erhalten:

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" 

der Fehler ist in der folgenden Zeile:

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

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

Ist es der richtige Weg, die Wrapper-Klasse "example_wrap.c" zu generieren?

+0

Sie haben ziemlich schlechte Formatierungsprobleme. –

+1

Nicht so schlecht, sie wussten nur nicht, den ganzen Code vier Leerzeichen einzurücken. Fest. – zwol

Antwort

5

Es gibt nicht genug Informationen hier, um sicher zu sein, was los ist, aber ich habe zwei Ideen für Dinge, die Sie ausprobieren können.

  1. Ihr g++ Aufruf wird die Erstellung einer C-Quelldatei, als ob es C++ waren. Dies ist nicht garantiert zu arbeiten. Versuchen Sie stattdessen

    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 
    

    (ja, srsly, nur verwenden g ++ für den Link)

  2. Wenn das nicht funktioniert, kompilieren example_wrap.c wie folgt aus:

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

Das wird auf die gleiche Weise fehlschlagen, aber eine Datei mit dem Namen example_wrap.i erzeugen, die das Ergebnis der Vorverarbeitung ist. Es wird gigantisch sein. Suchen Sie diese Datei nach der Funktion Swig_var_Math_get, und fügen Sie Ihrer Frage den vollständigen Text dieser Funktion hinzu (aber nichts anderes).

+0

Hoppla, example.cpp sollte mit g ++ kompiliert werden. Warum gcc? Vermeiden Sie C++ Mangeln? – jweyrich

+1

Es ist nur notwendig, 'g ++' zu verwenden, um zu verknüpfen. 'gcc -c' macht das Richtige, wenn es auf eine' .cpp' Quelldatei angewendet wird. Aber 'g ++ -c' tut * nicht * das Richtige, wenn es auf eine' .c' Quelldatei angewendet wird. Also die einfachste Regel zu erinnern ist, verwenden Sie immer "gcc" zu kompilieren, auch wenn die Quelle C++ ist; Verwenden Sie 'g ++' nur, um ein Programm zu verknüpfen, das C++ enthält. Gleiches gilt für alle anderen vom GCC unterstützten Sprachen: Verwenden Sie den sprachspezifischen Treiber nur zum Verknüpfen. Persönlich glaube ich nicht, dass die sprachspezifischen Treiber überhaupt existieren sollten, aber sie lassen Sie nicht genau wissen, wie man die Laufzeitbibliotheken aufruft. – zwol

+0

Nun, ja, Sie können GCC verwenden, um C++ zu kompilieren. Sie könnten auch gcc verwenden, um C++ zu verknüpfen, aber Sie müssten manuell gegen libstdC++ usw. verlinken. Auf diese Weise finde ich es einfacher, gcc für C und g ++ für C++ zu verwenden. Aber es ist nur persönlicher Geschmack. Das Wichtige ist, dass Problem und Lösung richtig herausgestellt wurden. +1 – jweyrich

13

Ich denke, der swig Befehl "swig -C++ -python example.swig"

0

Vielen Dank für Ihre Wiederholung sein soll!

Die -C++ -Option generiert die C++ - Klasse für den Wrapper. swig -C++ -v -python beispiel.swig

Ich habe g ++ verwendet, um den Wrapper zu kompilieren.

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

Und der folgende Befehl, um das gemeinsame Objekt zu buikd. Natürlich müssen wir die überflüssigen Includes (-I) und Libraries (-L) entfernen. Die wichtigen Flaggen sind "-shared" und "-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