How can I use a PyObject in C++?

Nick Craig-Wood nick at craig-wood.com
Wed Sep 24 06:30:06 EDT 2008


lixinyi.23 at gmail.com <lixinyi.23 at gmail.com> wrote:
>  for example:
>  #include <Python.h>
> 
>  void exec_python_code(int arg, char** argv)
>  {
>      Py_Initialize();
>      Py_Main(argc,argv);
>      Py_Finalize();
>  }
> 
>  What I would like to know is:
>  after  Py_Main(argc,argv);
> 
>  How do I get every variable in python space,
>  say a=[1,2,3,'Hello World',[2,3]]
>  b=['xx','xxx','ffff',0.1234] , and use them in C++?
> 
>  any sample code?
>  Thanks in advance!

Here is a bit of code I wrote yesterday which calls a python function
imported from a module and processes the result.

It would only be a dozen lines if it weren't for the error handling!
The code was compiled with a C++ compiler.

Read the python C API docs for more info (these work fine in C++ also)

  http://docs.python.org/api/api.html

Note it is very important to keep track of who owns which object -
hence the comments about /* new ref */ and /* borrowed */

Yes it uses goto... I find it is the easiest way of error handling in
C and making sure you don't leak objects on error conditions ;-)

/* Call the python function MyModule.SubModule.my_function() and
return the result as a malloc-ed string or 0 if there was a problem or
my_function returned None */

char *my_function(void)
{
    char *my_result = 0;
    PyObject *module = 0;
    PyObject *result = 0;
    PyObject *module_dict = 0;
    PyObject *func = 0;

    module = PyImport_ImportModule((char *)"MyModule.SubModule"); /* new ref */
    if (module == 0)
    {
        PyErr_Print();
        printf("Couldn't find python module MyModule.SubModule");
        goto out;
    }
    module_dict = PyModule_GetDict(module); /* borrowed */
    if (module_dict == 0)
    {
        PyErr_Print();
        printf("Couldn't find read python module MyModule.SubModule");
        goto out;
    }
    func = PyDict_GetItemString(module_dict, "my_function"); /* borrowed */
    if (func == 0)
    {
        PyErr_Print();
        printf("Couldn't find MyModule.SubModule.my_function");
        goto out;
    }
    result = PyEval_CallObject(func, NULL); /* new ref */
    if (result == 0)
    {
        PyErr_Print();
        printf("Couldn't run MyModule.SubModule.my_function");
        goto out;
    }
    else if (result == Py_None)
    {
        printf("MyModule.SubModule.my_function returned None");
        goto out;
    }
    my_result = PyString_AsString(result); /* borrowed */
    if (my_result == 0)
    {
        PyErr_Print();
        printf("Couldn't read result from MyModule.SubModule.my_function");
        goto out;
    }
    my_result = strdup(my_result); /* keep in our own memory */
out:;
    Py_XDECREF(result);
    Py_XDECREF(module);
    return my_result;
}

-- 
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick



More information about the Python-list mailing list