Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a python method from C/C++, and extracting its return value

I'd like to call a custom function that is defined in a Python module from C. I have some preliminary code to do that, but it just prints the output to stdout.

mytest.py

import math  def myabs(x):     return math.fabs(x) 

test.cpp

#include <Python.h>  int main() {     Py_Initialize();     PyRun_SimpleString("import sys; sys.path.append('.')");     PyRun_SimpleString("import mytest;");     PyRun_SimpleString("print mytest.myabs(2.0)");     Py_Finalize();      return 0; } 

How can I extract the return value into a C double and use it in C?

like image 461
D R Avatar asked Jul 20 '10 01:07

D R


1 Answers

As explained before, using PyRun_SimpleString seems to be a bad idea.

You should definitely use the methods provided by the C-API (http://docs.python.org/c-api/).

Reading the introduction is the first thing to do to understand the way it works.

First, you have to learn about PyObject that is the basic object for the C API. It can represent any kind of python basic types (string, float, int,...).

Many functions exist to convert for example python string to char* or PyFloat to double.

First, import your module :

PyObject* myModuleString = PyString_FromString((char*)"mytest"); PyObject* myModule = PyImport_Import(myModuleString); 

Then getting a reference to your function :

PyObject* myFunction = PyObject_GetAttrString(myModule,(char*)"myabs"); PyObject* args = PyTuple_Pack(1,PyFloat_FromDouble(2.0)); 

Then getting your result :

PyObject* myResult = PyObject_CallObject(myFunction, args) 

And getting back to a double :

double result = PyFloat_AsDouble(myResult); 

You should obviously check the errors (cf. link given by Mark Tolonen).

If you have any question, don't hesitate. Good luck.

like image 190
ThR37 Avatar answered Sep 20 '22 18:09

ThR37