2012-12-05 17 views
6

Ich versuche, einen einfachen Aufruf durch Verweis von Python in eine C++ - Klassenmethode zu tun.Boost-Python-Methodenaufrufe mit Referenzargumenten

Meine C++ Code wie folgt aussieht:

class Foo { 
protected: 
    int _internalVal; 
public: 
    Foo() : _internalVal(5){} 
    void getVal(int& val_io) {val_io = _internalVal;} 
    void getValDoesNothing(int val_io) {val_io = _internalVal;} 
} 

Mein Boost-Wrapper-Code, die fein kompiliert ist:

BOOST_PYTHON_MODULE(libBar) { 
    boost::python::class_<Foo>("Foo") 
    .def("getVal", &Foo::getVal) 
    .def("getValDoesNothing", &Foo::getValDoesNothing); 
} 

Allerdings, wenn ich die folgenden Python telefonieren:

In [1]: import libBar 

In [2]: f = libBar.Foo() 

In [3]: f 
Out[3]: <libBar.Foo at 0x2b483c0> 

In [4]: val = int() 

In [5]: #next command is just to check function signature type 

In [6]: f.getValDoesNothing(val) 

In [7]: f.getVal(val) 
--------------------------------------------------------------------------- 
ArgumentError        Traceback (most recent call last) 
<ipython-input-5-531e4cea97c2> in <module>() 
----> 1 f.getVal(val) 

ArgumentError: Python argument types in 
    Foo.getVal(Foo, int) 
did not match C++ signature: 
    getVal(Foo {lvalue}, int {lvalue}) 

I Ich arbeite mit einer Bibliothek, die ich nicht kontrolliere, also ist das Ändern von getVal, um den Wert zurückzugeben, keine Option.

Gibt es eine Möglichkeit, den letzten Python-Befehl zu arbeiten?

Ich nehme sogar eine Korrektur, die die Python-Variable nicht ändert, aber immer noch den Funktionsaufruf erlaubt.

Antwort

5

Was Sie erreichen möchten, ist in Python nicht gültig. Ganzzahlen sind unveränderlich, daher kann man nicht einfach eine Funktion aufrufen und hoffen, dass sie ihren Inhalt ändert.

Da Sie mit einer Bibliothek, die Sie kontrollieren nicht arbeiten und getVal Ändern Sie den Wert zurückzukehren ist keine Option, erhalten Sie einen Wrapper so erstellen:

int getVal(Foo &foo) { 
    int val_io; 
    foo.getVal(val_io); 
    return val_io; 
}; 

BOOST_PYTHON_MODULE(libBar) { 
    boost::python::def("getVal", getVal); 
    ... 
} 

und verwenden Sie dann auf diese Weise :

In [1]: import libBar 

In [2]: f = libBar.Foo() 

In [3]: f 
Out[3]: <libBar.Foo at 0x2b483c0 

In [3]: libBar.getVal(f) 
Out[3]: 5 
-1

In getValDoesNothing übergeben Sie eine Int. In getVal übergeben Sie einen Verweis auf ein int.

Ich glaube, das ist die Quelle Ihres Problems.

+0

Ich weiß, ich bin in einer Referenz übergeben. Meine Frage ist, wie mache ich das? –