<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transational//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=UTF-8">
</HEAD>
<BODY>Hi Stephen<br><br>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.<br><br>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<br>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)<br><br>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.<br><br>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<br><br><br>  // WE pass a tuple<br>  pTuple = PyTuple_New(10);<br>  if (pTuple == NULL) {<br>    Py_DECREF(pTuple);<br>    cout << "Can't build argument list for method call\n";<br>  }<br>  <br>  PyObject  *py_argument;<br>  <br>  for (int i = 0 ; i < 10 ; i++ ) {<br>     py_argument = PyFloat_FromDouble(5.*(double)i);<br>     PyTuple_SetItem(pTuple, i, py_argument);<br>  }<br>  <br>  args = Py_BuildValue("(O)", pTuple);<br>  if (args == NULL) {<br>    Py_DECREF(args);<br>    error("Can't build argument list for class instance");<br>  }<br>  <br>  // Call our object method with arguments <br>  ret = PyEval_CallObject(method,args);<br><br><br><br><br><br><br>
---- Message d'origine ----<br>
De : pasparis@noos.fr<br>
À : python-list@python.org<br>
Objet : C-API: Pass a tuple to a method of a class<br>
Date : 10/01/2012 11:57:38 CET<br>
<br>
Hello<br><br>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. <br>thanks for help/suggestions<br><br>the code is the following:<br><br><br>Python Code:<br><br>class cVector:<br>  def __init__(self,msg):<br>    self.value = msg<br>  def ComputeNorm(self,vecData):<br>    #don't use vecData for instance<br>    result = 12.<br>    return(result)<br><br><br>C++ Code :<br>//instances. farenheit will hold our return value <br>  PyObject *ret, *mymod, *pclass, *method, *args, *object;<br>  float retValue;<br><br>  Py_Initialize();<br>  //PySys_SetPath("/home/pascal/projPytCpp/proj1");<br>  PySys_SetPath(".");<br>  <br>  // Module<br>  mymod = PyImport_ImportModule("mModule8");<br>  if (mymod == NULL){<br>    cout << "Can't Open a module:\n" ;<br>    Py_DECREF(mymod);<br>  }<br>  <br>  // Class<br>  pclass = PyObject_GetAttrString(mymod, "cVector");<br>  if (pclass == NULL) {<br>    Py_DECREF(pclass);<br>    cout << "Can't find class\n";<br>  }<br>  <br>  // Parameters/Values<br>  args = Py_BuildValue("(f)", 100.0);<br>  if (args == NULL) {<br>    Py_DECREF(args);<br>    cout << "Can't build argument list for class instance\n";<br>  }<br>  <br>  // Object with parameter/value<br>  object = PyEval_CallObject(pclass, args);<br>  if (object == NULL) {<br>    Py_DECREF(object);<br>    cout << "Can't create object instance:\n";<br>  }<br>  <br>  // Decrement the argument counter as we'll be using this again <br>  Py_DECREF(args);<br>  <br>  // Get the object method - note we use the object as the object<br>  // from which we access the attribute by name, not the class <br>  method = PyObject_GetAttrString(object, "ComputeNorm");<br>  if (method == NULL) {<br>    Py_DECREF(method);<br>    cout << "Can't find method\n";<br>  }<br>  <br>  // Decrement the counter for our object, since we now just need<br>  // the method reference <br>  Py_DECREF(object);<br><br>  // Build our argument list - an empty tuple because there aren't<br>  // any arguments <br>  <br>  cout << "Prepare the Tuple:\n" ;<br>  // WE pass a tuple<br>  args = PyTuple_New( 3 );<br>  if (args == NULL) {<br>    Py_DECREF(args);<br>    cout << "Can't build argument list for method call\n";<br>  }<br>  <br>  PyObject  *py_argument;<br>  // 1st argument <br>  py_argument = PyFloat_FromDouble(5.);<br>  PyTuple_SetItem(args, 0, py_argument);<br> <br>  // 2nd argument <br>  py_argument = PyFloat_FromDouble(10.);<br>  PyTuple_SetItem(args, 1, py_argument);<br>  <br>  // 3nd argument <br>  py_argument = PyFloat_FromDouble(15.);<br>  PyTuple_SetItem(args, 2, py_argument);<br>  <br>  cout << "Before the Exec:\n" ;<br>  // Call our object method with arguments <br>  //ret = PyEval_CallObject(method,args);<br>  ret = PyObject_CallObject(method,args);<br>  if (ret == NULL) {<br>    Py_DECREF(ret);<br>    cout << "Couldn't call method\n";<br>  }<br>  <br><br>  // Convert the return value back into a C variable and display it <br>  PyArg_Parse(ret, "f", &retValue);<br>  printf("Farenheit: %f\n", retValue);<br>  // Kill the remaining objects we don't need <br>  Py_DECREF(method);<br>  Py_DECREF(ret);<br>  // Close off the interpreter and terminate <br>  Py_Finalize();<br>  <br></BODY></HTML>