[C++-sig] Re : changing argument value in a C++/Python code

christophe jean-joseph jjchristophe at yahoo.fr
Fri Jun 8 14:46:13 CEST 2012



As my code was uncommented and uncomplete, I post it again with necessary corrections.

C++ classes:

#include <iostream>
using namespace std;

/*
Class aimed at modeling a C++ user's type that should be used in Python
*/

class C
{
public:
double myC;
C(){}
~C(){}

void setValue(double val) {
myC = val;
    }

    double getValue() {
return myC;
    }
};

/*
This class will be derived in Python
We want to be sure that:
- void (g) and non void (f) functions are properly reflected and extended in Python
- a function (h) with a local type (C) will properly use the python overloaded function of a C++ function (g)
*/

class A
{
public:
A(){int A_x=0;}
virtual ~A(){}
virtual int f(int Ivar){
Ivar = 0;
return Ivar;
}
virtual void g(C * myC){
C calledC;
cout << "I should not be here" << endl;   //When B::setparam call g, it should be the Python g, not the virtual function from base class
calledC.setValue(0.);
}
C h(){//This function wont be overloaded in Python
C myC;
this->g(&myC);//We want myC to be modified, and the python overloaded version of g to be used
C calledC;
double myCint;
myCint = calledC.getValue();
cout << "Value back in C++: " << myCint << endl; //We want to verify if myC has been modified back in C++
myCint = myCint*2;
calledC.setValue(myCint);
return myC;
}
};

/*
This class will be called from a main in Python.
It's function setparam is aimed at ensuring that Python extension of a C++ class is supported properly
*/

class B
{
public:
B(A & a){
setparam(a); 
}
B(){
int u;
u = 0;
}
virtual ~B(){}
void setparam(A & a){
a.h();//Here the code should call the h overloaded function of the derived class of A in Python
}
};

Boost::Python Wrapper:

#include <boost/python.hpp>
#include <Python.h>
#include <object.h>
#include "ClassA.h"

#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/implicit.hpp>
#include <iostream>
using namespace std;

using namespace boost::python;

/*
A wrapper is used to allow overload of virtual A function
*/
struct WrapperClassA : A, boost::python::wrapper<A>{
int f(int Ivar){
if(override f = this->get_override("f")){
return f(Ivar);
}
else {
return A::f(Ivar);
}
}
int default_f(int Ivar){
return this->A::f(Ivar);
}

void g(C * myC){
if(override g = this->get_override("g")){
g(myC);
}
else {
A::g(myC);
}
}
void default_g(C * myC){
this->A::g(myC);
}
};

/*
Refection of necessary classes and functions for Python
*/
BOOST_PYTHON_MODULE(myWrapper){
class_<WrapperClassA, boost::noncopyable>("A", init<>())
.def("f", &A::f, &WrapperClassA::default_f)
.def("g", &A::g, &WrapperClassA::default_g)
;

class_<B, boost::noncopyable>("B", init<>())
.def("setparam", &B::setparam)
;

    class_<C>("C", init<>())
    .def("setValue", &C::setValue)
    .def("getValue", &C::getValue)
    .def_readwrite("myC", &C::myC)
    ;
}

Python code:

from math import *
# C++ library
from myWrapper import *

"""
Extension of C++ class A
APy be used when A type argument is called
g should be able to use a C++ C type object and to modify it
"""
class APy(A):
def __init__(self):
A.__init__(self)
n = 0
x = 0.
def f(self, n):
n = 5
return n
def g(self, myC):
calledC = C()
x = 7.0
calledC.setValue(x)
print("value in Python: " + repr(calledC.getValue()))

"""
Main
myB.setparam should be able to pass a APy argument
"""
myA = APy()
myB = B()
myB.setparam(myA)


When I run the code, print("value in Python: " + repr(calledC.getValue()))  print 7, but cout << "Value back in C++: " << myCint << endl print -9.25596e+061 while I would like the variable to be at 7.

Thank you for any help.

CHRISTOPHE Jean-Joseph
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20120608/622dec0f/attachment.html>


More information about the Cplusplus-sig mailing list