[C++-sig] Re: Make C++-created object accessible by embeded Python Script

Raoul Gough RaoulGough at yahoo.co.uk
Mon Oct 27 23:33:37 CET 2003


dique <chezdique at yahoo.com> writes:

> Hi all,
>
> I have several C++ objects (created with C++ code) and
> I want them to be accessible and manipulatable by an
> embeded python script. So far I only manage to let the
> embeded script access a _copy_ of the C++ object.
> Hence whatever changes done to the C++ object in the
> python script wouldn't have any effect on the C++
> object running in C++ code. How do I make the embeded
> script able to access and manipulate the C++ object
> directly?
>
> I hope the code below would demonstrate what I mean.
>
> #include <string>
> #include <iostream>
> #include <boost/python.hpp>
>
> using namespace boost::python;
[snip]
>     // This works nicely. But only limited to objects
> created by Python.
>     object testClass = class_<Test>("Test",
> init<int>())
>         .def("add", &Test::add);
>     object testObject = testClass(10);
>     pythonScript.addNamedObject("test", testObject);
>     Test& test = extract<Test&>(testObject)();
>     std::cout << "C++: " << test.add(10) << std::endl;
>     pythonScript.run("print 'Python:',
> test.add(10)\n");
>     std::cout << "C++: " << test.add(10) << std::endl;
>
>     // Below doesn't work as expected,
>     // as Python and C++ maintain separate copies of test1.
>     Test test1(10);
>     object testObject1(test1);
>     pythonScript.addNamedObject("test1", testObject1);
>     std::cout << "C++: " << test1.add(10) <<
> std::endl;
>     pythonScript.run("print 'Python:',
> test1.add(10)\n");
>     std::cout << "C++: " << test1.add(10) <<
> std::endl;

You could probably get what you want using boost::shared_ptr as the
"HeldType" for use in the Python object. Basically, the problem is
that you want to embed a reference of some sort to the C++ object
within the Python object. This is dangerous unless you have some way
of linking the lifetime of the C++ object to that of the Python object
that references it. I think it would just be a matter of doing it like
this:

object testClass = class_<Test, std::shared_ptr<Test> >(
   "Test", init<int>())
   .def("add", &Test::add);

boost::shared_ptr<Test> test1ptr (new Test (10));
object testObject1 (test1ptr); // ?
// ...

Not too sure of the exact details, but hopefully that gives you the
basic idea. See the libs/python/doc/v2/class.html for details.

-- 
Raoul Gough.
(setq dabbrev-case-fold-search nil)





More information about the Cplusplus-sig mailing list