Hi Stephen

Thanks for examining and advise a solution. Before testing CPython I wanted to run this very simple think to send a tuple to a method of a python class.

I have succeeded in sending a tuple (declared exactly the same way as I do in the code) to a method written in a python file
but as soon as you put the method in a class and try to send a tuple it doesn't work(get a run failed message)

I don't send 3 arguments, it's a mistake from me to code that way,it leads to misunderstanding, it's 3 items in one tuple (declared args), 3 is just chosen by sample, it has to be dynamic later to send a series of data in a tuple.

I modifed the code and try to do this thing: (again it works when the method doesn't belong to a class and this what is very "strange" for me) and it's still doesn't work


  // WE pass a tuple
  pTuple = PyTuple_New(10);
  if (pTuple == NULL) {
    Py_DECREF(pTuple);
    cout << "Can't build argument list for method call\n";
  }
 
  PyObject  *py_argument;
 
  for (int i = 0 ; i < 10 ; i++ ) {
     py_argument = PyFloat_FromDouble(5.*(double)i);
     PyTuple_SetItem(pTuple, i, py_argument);
  }
 
  args = Py_BuildValue("(O)", pTuple);
  if (args == NULL) {
    Py_DECREF(args);
    error("Can't build argument list for class instance");
  }
 
  // Call our object method with arguments
  ret = PyEval_CallObject(method,args);






---- Message d'origine ----
De : paspa...@noos.fr
À : python-list@python.org
Objet : C-API: Pass a tuple to a method of a class
Date : 10/01/2012 11:57:38 CET

Hello

I am trying to pass a tuple to a method of a class from C++ to Python. I get a Run Failed from the execution.
thanks for help/suggestions

the code is the following:


Python Code:

class cVector:
  def __init__(self,msg):
    self.value = msg
  def ComputeNorm(self,vecData):
    #don't use vecData for instance
    result = 12.
    return(result)


C++ Code :
//instances. farenheit will hold our return value
  PyObject *ret, *mymod, *pclass, *method, *args, *object;
  float retValue;

  Py_Initialize();
  //PySys_SetPath("/home/pascal/projPytCpp/proj1");
  PySys_SetPath(".");
 
  // Module
  mymod = PyImport_ImportModule("mModule8");
  if (mymod == NULL){
    cout << "Can't Open a module:\n" ;
    Py_DECREF(mymod);
  }
 
  // Class
  pclass = PyObject_GetAttrString(mymod, "cVector");
  if (pclass == NULL) {
    Py_DECREF(pclass);
    cout << "Can't find class\n";
  }
 
  // Parameters/Values
  args = Py_BuildValue("(f)", 100.0);
  if (args == NULL) {
    Py_DECREF(args);
    cout << "Can't build argument list for class instance\n";
  }
 
  // Object with parameter/value
  object = PyEval_CallObject(pclass, args);
  if (object == NULL) {
    Py_DECREF(object);
    cout << "Can't create object instance:\n";
  }
 
  // Decrement the argument counter as we'll be using this again
  Py_DECREF(args);
 
  // Get the object method - note we use the object as the object
  // from which we access the attribute by name, not the class
  method = PyObject_GetAttrString(object, "ComputeNorm");
  if (method == NULL) {
    Py_DECREF(method);
    cout << "Can't find method\n";
  }
 
  // Decrement the counter for our object, since we now just need
  // the method reference
  Py_DECREF(object);

  // Build our argument list - an empty tuple because there aren't
  // any arguments
 
  cout << "Prepare the Tuple:\n" ;
  // WE pass a tuple
  args = PyTuple_New( 3 );
  if (args == NULL) {
    Py_DECREF(args);
    cout << "Can't build argument list for method call\n";
  }
 
  PyObject  *py_argument;
  // 1st argument
  py_argument = PyFloat_FromDouble(5.);
  PyTuple_SetItem(args, 0, py_argument);
 
  // 2nd argument
  py_argument = PyFloat_FromDouble(10.);
  PyTuple_SetItem(args, 1, py_argument);
 
  // 3nd argument
  py_argument = PyFloat_FromDouble(15.);
  PyTuple_SetItem(args, 2, py_argument);
 
  cout << "Before the Exec:\n" ;
  // Call our object method with arguments
  //ret = PyEval_CallObject(method,args);
  ret = PyObject_CallObject(method,args);
  if (ret == NULL) {
    Py_DECREF(ret);
    cout << "Couldn't call method\n";
  }
 

  // Convert the return value back into a C variable and display it
  PyArg_Parse(ret, "f", &retValue);
  printf("Farenheit: %f\n", retValue);
  // Kill the remaining objects we don't need
  Py_DECREF(method);
  Py_DECREF(ret);
  // Close off the interpreter and terminate
  Py_Finalize();
 
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to