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

christophe jean-joseph jjchristophe at yahoo.fr
Fri Jun 8 11:49:10 CEST 2012



My problem is as follow:
I have a C++ code that I can't modify as I want (not written by me and under some intellectual property constraints). I have to link it with a Python code through a Python main.
I use boost::python for the reflection.
At some point in the code, a C++ function use a Python overloaded function of a C++ function to modify a parameter. This function works great when used inside Python. But when called by a C++ function, the modification of the parameter will not be taken into account while back in C++.
To model the problem, I wrote a simplified version aimed at isolating my problem.

Here are the C++ classes:

#include <iostream>
using namespace std;
#include <vector>

class A
{
public:
A(){int A_x=0;}
virtual ~A(){}
virtual int f(int Ivar){
Ivar = 0;
return Ivar;
}
virtual void g(double Dvar){
Dvar = 0.;
}
double h(){
double Dvar;
Dvar = 0.;
this->g(Dvar);
cout << Dvar << endl;
Dvar = Dvar*2;
return Dvar;
}
};

class B
{
public:
B(A & a){
setparam(a); 
}
B(){
int u;
u = 0;
}
virtual ~B(){}
void setparam(A & a){
a.h(); 
}
};

The boost python wrapper:

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

//#include <boost/python/cross_module.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/implicit.hpp>
#include <iostream>
using namespace std;
#include <vector>

using namespace boost::python;

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(double Dvar){
if(override g = this->get_override("g")){
g(Dvar);
}
else {
A::g(Dvar);
}
}
void default_g(double Dvar){
this->A::g(Dvar);
}
};
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)
;
}

The Python code:

from math import *
import random
# Our Ilab library
from myWrapper import *
# Allow option choices.
import argparse

class APy(A):
def __init__(self):
A.__init__(self)
n = 0
x = 0.
def f(self, n):
n = 5
return n
def g(self, x):
x = 7.0
print("value in Python: " + repr(x))

myA = APy()
myB = B()
myB.setparam(myA)

When I run the code, print("value in Python: " + repr(x)) print 7, but cout << Dvar << endl print 0 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/ff9839dd/attachment.html>


More information about the Cplusplus-sig mailing list