2012-12-05 17 views
6

Sto provando a eseguire una semplice chiamata mediante riferimento da python a un metodo di classe C++.chiamate di metodo boost Python con argomenti di riferimento

mio codice C++ si presenta come:

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;} 
} 

La mia spinta codice wrapper che compila bene è:

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

Tuttavia quando faccio le seguenti chiamate pitone:

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 Sto lavorando con una libreria che non controllo, quindi cambiare getVal per restituire il valore non è un'opzione.

C'è un modo per far funzionare l'ultimo comando Python?

Prenderò anche una correzione che non modifica la variabile Python ma consente comunque la chiamata di funzione.

risposta

5

Quello che stai cercando di ottenere non è valido in Python. Gli integer sono immutabili, quindi non è possibile chiamare semplicemente una funzione e sperare che cambierà il suo contenuto.

Dal momento che si sta lavorando con una libreria che non controlli e cambiando GetVal per restituire il valore non è un'opzione, è possibile creare un involucro simile:

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

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

e quindi utilizzare in questo modo :

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 stai passando un int. In getVal stai passando un riferimento a un int.

Credo che questa sia la fonte del tuo problema.

+0

So che sto passando un riferimento. La mia domanda è come posso farlo? –

Problemi correlati