2016-12-06 2 views
1

Ich mache Python-Wrapper für C++ - Bibliothek.Eingabe-Sting für Wrapped C++ - Funktion ändert sich nicht SWIG

mylib.i:

%module mylib 
%include <std_string.i> 

%{ 
    #include "mylib.h" 

%} 
%apply const std::string & {std::string &}; 
%apply std::string & {std::string &}; 

int getResult(const std::string& path, std::string& result); 

mylib.h:

#pragma once 

#include <string> 

myEnum {foo=0, bar}; 
myEnum getResult(const std::string& path, std::string& result); 

Nach dem Erzeugen _mylib.so mit folgenden Befehl ein:

g++ -fPIC -Wall -Wextra -shared mylib_wrap.cxx -o _mylib.so -L. -lmylib -I/usr/include/python2.7/ -lpython2.7 

ich als nächstes tun:

LD_LIBRARY_PATH=. python Python 2.7.2 (default, Dec 6 2016, 10:43:39) 
[GCC 4.8.4] on linux4 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import _mylib 
>>> result= "" 
>>> x = _mylib.getResult("somePath",result) 

Nach der Ausführung meiner Funktion, x gibt die richtige Antwort der Methode zurück. Auch ich habe Konsolenausgabe von meiner Funktion. Die Ergebniszeichenfolge ändert sich jedoch nicht. Wenn ich die Ergebniszeichenfolge mit "einigen Text" initiiere, und meine Funktion erneut aufrufen, print result zurückgeben "some text". Was mache ich falsch?

+0

Wenn Sie diesen Code betrachten, übergeben Sie die Variable 'json', nicht die Variable' result', also würde ich nicht erwarten, dass sie die Variable 'result' ändert. – Petesh

+0

@Petesh Sorry, habe den Variablennamen nach Copypaste vergessen. –

+0

@Petesh aber mit dem richtigen Eingangsparameternamen, Problem nicht verschwunden. –

Antwort

1

Der einfachste Weg, dies zu bekommen in Ihrer Schnittstelle zu arbeiten, ist %inline zu verwenden, um eine Überlastung zu schaffen, die das Ergebnis stattdessen zurückgibt:

%module mylib 
%include <std_string.i> 

%{ 
    #include "mylib.h" 
%} 

%inline %{ 
    int getResult(const std::string& path) { 
     std::string temp; 
     const int ret = getResult(path, temp); 
     if (ret != good) abort(); // TODO exceptions 
     return temp; 
    } 
%} 

Sie brauchen nicht einmal SWIG zu zeigen, die reale Version von getResult .

Es gibt andere Optionen (z. B. verwenden Sie eine Eingabe typemap mit numinputs = 0 und eine argout typemap, um den Rückgabewert zu ändern), aber sie sind komplizierter und in der Regel weniger portabel für andere Sprachen.

+0

Ehrfürchtig. Es funktioniert. Thant du. –

+0

Kann ich Code von% inline in .cpp-Datei [email protected] –

+0

@VolodymyrHnatiuk sicher, oder Sie können es in '% {%}' stattdessen teilen, aber Sie am Ende schreiben Bits davon (d. H. Die Erklärung) zweimal dann – Flexo

1

Egal wie viel Trick SWIG in diesem Fall tut, kann es nicht umgehen, dass Python-Strings unveränderlich sind - einmal festgelegt, können Sie sie nicht ändern.

Die SWIG generierten Code vage wie folgt aussieht:

std::string *arg1 = make a new std::string from path; 
std::string *arg2 = make a new std::string from result; 
result = (int)getResult((std::string const &)*arg1,*arg2); 
resultobj = SWIG_From_int(static_cast<int>(result)); 
if (SWIG_IsNewObj(res1)) delete arg1; 
if (SWIG_IsNewObj(res2)) delete arg2; 

Beachten Sie, dass es eine neue Zeichenfolge aus den Saiten macht übergeben, und Nukes sie dann am Ende - immerhin Strings unveränderlich sind.

eine faule Lösung würde einfach die JSON-Zeichenfolge z. eine Schnittstelle von:

std::string getResult(std::string &path) 

würde den gewünschten Effekt haben.

Jetzt, wenn Sie einen speziellen Rückgabewert wünschen, sind es Objekte und alles, was damit verbunden wäre.

+0

Es ist nicht gut. Aber kann ich meine Funktionen irgendwie in Interface-Datei umhüllen. Definieren Sie in der Schnittstelle einige Funktionen, die Anruf getResult Funktion sein werden? –

+0

Sie sollten in der Lage sein, irgendeine Art von Verpackung zu machen, um das zu erreichen, was Sie wollen. Es ist wirklich wegen der Art, wie Python funktioniert, dass Sie diese Schnittstelle nicht so erhalten können, wie sie ist. – Petesh

Verwandte Themen