[C++-sig] Make C++-created object accessible by embeded Python Script
dique
chezdique at yahoo.com
Mon Oct 27 10:02:14 CET 2003
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;
BOOST_PYTHON_MODULE(_pyembed)
{
// To define useful functions.
}
class PythonScript
{
public:
PythonScript()
{
PyImport_AppendInittab("_pyembed",
init_pyembed);
Py_Initialize();
handle<> mainModule(borrowed(
PyImport_AddModule("__main__") ));
mainNamespace_ = dict(handle<>(borrowed(
PyModule_GetDict(mainModule.get()))));
}
virtual ~PythonScript()
{
Py_Finalize();
}
//! Add a named object which will be accessible by
the script.
virtual void addNamedObject(const std::string&
name, object& obj)
{
dict_[name] = obj;
}
//! Run the script.
virtual void run(const std::string& script)
{
mainNamespace_.update(dict_);
try
{
object result(handle<>(
PyRun_String(script.c_str(), Py_file_input,
mainNamespace_.ptr(),
mainNamespace_.ptr()) ));
}
catch(error_already_set)
{
PyErr_Print();
}
}
private:
dict dict_;
dict mainNamespace_;
};
class Test
{
public:
Test(int i) : i_(i) {}
int add(int j)
{
return i_ += j;
}
private:
int i_;
};
class Test2
{
public:
Test2(int i) : i_(i) {}
int add(int j)
{
return i_ += j;
}
private:
int i_;
};
int main(int argc, char* argv[])
{
PythonScript pythonScript;
// 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;
// Another attempt which failed too.
try
{
Test2 test2(10);
object testClass2 = class_<Test2,
boost::noncopyable>("Test2", init<int>())
.def("add", &Test2::add);
object testObject2(test2);
pythonScript.addNamedObject("test2",
testObject2);
std::cout << "C++: " << test2.add(10) <<
std::endl;
pythonScript.run("print 'Python:',
test2.add(10)\n");
std::cout << "C++: " << test2.add(10) <<
std::endl;
}
catch(error_already_set)
{
PyErr_Print();
}
return 0;
}
Thanks,
Dique C.
__________________________________
Do you Yahoo!?
Exclusive Video Premiere - Britney Spears
http://launch.yahoo.com/promos/britneyspears/
More information about the Cplusplus-sig
mailing list