2013-03-03 5 views
8

Ich habe eine C++ - Funktion, in der zwei Argumente wie im folgenden Beispiel angegeben sind.Wie erhalten Referenz- und Zeigerargumente in Python + SWIG?

void func(int& n, char** data) 
{ 
    *data = other_func1(); // returns a char array 
    n = other_func2(); // returns the length of the array 
} 

Ich kann leicht diese Funktion in C oder C++ verwenden, aber ich weiß nicht, wie ich es von einem Python-Modul mit SWIG generiert aufrufen können. Ich nehme an, dass ich eine andere C++ - Funktion schreiben muss, die zum Beispiel std :: pair zurückgibt. Aber wenn möglich, würde ich gerne einen Workaround auf der Python-Seite kennenlernen. Könnte jemand helfen?

Antwort

8

Für eine ganze Reihe von Fällen (z int *n) es ausreichen würde zu schreiben:

%apply int *OUTPUT { int *n }; 

, die einige Standards typemaps verwendet, die SWIG für Ausgabeparameter zur Verfügung stellt. (Es gibt auch INOUT und INPUT, die ähnlich sind).

In dieser Instanz stimmen wir zwar nicht wirklich mit den vordefinierten Fällen überein, müssen also manuell dasselbe tun. Das sind im Grunde zwei Typemaps pro Argument - eine Input Typmap, die etwas temporäres für den eigentlichen Funktionsaufruf erzeugt und anstelle einer echten Eingabe ein Argument verwendet, das das Ergebnis vom temporären Python zurückbringt. Im Fall von Python ist es sinnvoll, ein Tupel für die Rückgabe mehrerer Argumente zu verwenden.

Ein Beispiel:

%module test 

%typemap(in,numinputs=0) int& n (int temp) "$1 = &temp;" 
%typemap(in,numinputs=0) char **data (char *temp) "$1 = &temp;" 

%typemap(argout) char **data { 
    %append_output(PyString_FromString(*$1)); 
} 

%typemap(argout) int& n { 
    %append_output(PyInt_FromLong(*$1)); 
} 

%inline %{ 
    void foo(int& n, char **data) { 
    static char str[] = "Hello world"; 
    *data = str; 
    n = sizeof str; 
    } 
%} 

Punkte zu beachten:

Die temporären Variablen (int temp, char *temp) automatisch umbenannt bekommen, die den scheinbaren Namen Zusammenstoß stoppt. %append_output ist ein SWIG-Makro, das erweitert wird, um etwas an die Rückseite des $result Tupels in Python hinzuzufügen. Wenn Ihre Funktion foo dynamisch zugewiesenen Speicher wäre, müssten Sie damit umgehen. Die Freearg-Typenmap ist oft nützlich, wenn die In-Typ-Map Speicher dynamisch zuweisen muss.

Dies reichte aus, um mir zu erlauben, zu kompilieren und es gerne laufen:

import test 

len,str = test.foo() 

print len 
print str