[C++-sig] Calling python function from C++

David Abrahams dave at boost-consulting.com
Wed Nov 13 04:08:43 CET 2002


"Bjorn Pettersen" <BPettersen at NAREX.com> writes:

> In http://www.boost.org/libs/python/doc/v2/callbacks.html it says
> "...given an _object_ instance f holding the function...", however I
> can't find a simple way to get a reference to a Python function into
> an object instance.
>
> My test code is:
>
>     PyRun_String(
>         "def hello(s):              \n"
>         "    return 'hello ' + s    \n",
>         Py_file_input, ns, ns);

The PyRun_String docs say:

  PyObject* PyRun_String(char *str, int start, PyObject *globals, PyObject *locals) 
  Return value: New reference. 
                ^^^^^^^^^^^^^

Which means you're leaking a reference here.

>     PyObject* fn = PyRun_String("hello", Py_eval_input, ns, ns);
>
> I then want code with the same semantics as:
>
>     PyObject* res = PyObject_CallFunction(fn, "s", "world");
>     Py_DECREF(fn);
>     std::string cpp_res = PyString_AsString(res);
>     Py_DECREF(res);
>
> the closest I've gotten is:
>
>     object hello = object(handle<>(borrowed(fn)));

Why are you using borrowed()? That causes another reference to be
leaked.

>     object res = hello("world");
>     std::string cpp_res = extract<std::string>(res);
>
> I found the wrapping of 'fn' in the example in the "errors.hpp"
> section.  Is this the easiest/correct way to do this? 

You want something like:

  handle<> fn = PyRun_String("hello", Py_eval_input, ns, ns);
  object hello(fn);
  std::string cpp_res = extract<std::string>(hello("world"));

> Second
> question: are the reference counts in the Boost example all taken
> care of at end-of-scope?

Yes.

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution





More information about the Cplusplus-sig mailing list