[solved] Strange behaviour when calling C++ member function

Hi!

I’m trying to use a C++ class in my PyRoot code with Cint via gROOT.ProcessLine(). The strange thing is that the result of the public member function of this class is sometimes passed to Python, but sometimes not. This seems to depend on whether there’s a non-constant value in the parameter list of the method that I’m calling or not.
To illustrate what I’m doing here’s a minimal example:

This is the code of the C++ class (helper.cpp):

[code]class helper {
public:
double calc( double par1, double par2 );
};

double helper::calc( double par1, double par2 ) {
return par1 + par2;
}
[/code]

And this is my Python script:

#!/usr/bin/env python
from ROOT import *

gROOT.ProcessLine(".L helper.cpp++")
gROOT.ProcessLine("helper* myclass = new helper()")
gROOT.ProcessLine("double result1, result2")
for parameter in range(1, 2):
  #parameter = 9.1342
  print
  print parameter
  parameter1 = parameter
  print parameter1
  parameter2 = 2.345
  print parameter1 + parameter2
  gROOT.ProcessLine("result1 = myclass->calc("+str(parameter1)+","+str(parameter2)+")")
  gROOT.ProcessLine("result2 = myclass->calc(1.23,2.345)")
  print result1
  print result2

So, the moment I set parameter/parameter1 to a constant value (i.e. uncomment the first line in the for loop), the result is properly passed to Python, but otherwise not.

I already tried a lot of things like using a shared library, compiling the C++ code or not, using casts etc. but I couldn’t really find any solution and I’m still totally puzzled … :confused:

Any help will be highly appreciated!

Cheers,
Christian

PS: I’m using Python 2.4.3 and root 5.28/00a

Christian,

I don’t follow what you’re trying to accomplish … The global result1 and result2 from the global CINT scope are found because of the “from ROOT import*”. But they are only found once, then transferred, and then exist on the python side and are afterwards never looked up again. Thus, if you loop over those calls, result1 and result2 will always remain the same value they were when first set.

This is the same behavior as expected from pure python modules on which you do “from pymodule import *”: you get a local copy (locally bound reference) of all global variables. If you want the result1 and result2 to be updated after resetting them at the module level, you’d have delete them at the end of the loop (in the scope of the looping code), use “import ROOT” and re-access them on module ROOT every time, or use C++ pointers.

Cheers,
Wim

Thanks Wim,
this helped me a lot!
I changed my code and now I’m using pointers. For people interested, here’s the new minimal example that works as expected:

helper.cpp:

class helper {
  public:
    void calc( double par1, double par2, double* result );
};


void helper::calc( double par1, double par2, double* result ) {
  (*result) = par1 + par2;
  return (*result);
}

main.py:

#!/usr/bin/env python

from ROOT import *

gROOT.ProcessLine(".L helper.cpp++")
gROOT.ProcessLine("helper* myclass = new helper()")
gROOT.ProcessLine("double *result1 = new double(0)")
gROOT.ProcessLine("double *result2 = new double(0)")
for parameter in range(1, 3):
  print
  parameter1 = parameter
  parameter2 = 2.345
  print parameter1 + parameter2
  gROOT.ProcessLine("myclass->calc("+str(parameter1)+","+str(parameter2)+", result1)")
  gROOT.ProcessLine("myclass->calc(1,2.345,result2)")
  print result1[0]
  print result2[0]

Cheers,
Christian