
I'm trying embedding python using boost::python. Just as the same way as the boost::python quick start "embedding.cpp". I have a C++ base class, with a virtual function do something on another C++ object: struct MyClass { void printThis() { std::cout << "0x" << this << std::endl; } }; // An abstract base class class Base : public boost::noncopyable { public: virtual ~Base() {}; virtual void printMyClass(MyClass& myObj) = 0; }; Than, I want to write some Python derived class code: "from embedded_hello import * \n" "class PythonDerived(Base): \n" " def printMyClass(self, myObj): \n" " myObj.printThis() \n" But I found that the "myObj" passed to python code is another obj, not the object created in C++ code. How can use the object created in C++ object rather than a copyed object? Thanks! The full code list below, which is modified form boost::python example. // Copyright Stefan Seefeld 2005. // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include <boost/python.hpp> #include <boost/detail/lightweight_test.hpp> #include <iostream> namespace python = boost::python; struct MyClass { void printThis() { std::cout << "0x" << this << std::endl; } }; // An abstract base class class Base : public boost::noncopyable { public: virtual ~Base() {}; virtual std::string hello() = 0; virtual void printMyClass(MyClass& myObj) = 0; }; // C++ derived class class CppDerived : public Base { public: virtual ~CppDerived() {} virtual std::string hello() { return "Hello from C++!";} virtual void printMyClass(MyClass& myObj) { myObj.printThis(); } }; // Familiar Boost.Python wrapper class for Base struct BaseWrap : Base, python::wrapper<Base> { virtual void printMyClass(MyClass& myObj) { this->get_override("printMyClass")(myObj); } virtual std::string hello() { #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // workaround for VC++ 6.x or 7.0, see // http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#pyth... return python::call<std::string>(this->get_override("hello").ptr()); #else return this->get_override("hello")(); #endif } }; // Pack the Base class wrapper into a module BOOST_PYTHON_MODULE(embedded_hello) { python::class_<BaseWrap, boost::noncopyable> base("Base"); python::class_<MyClass>("MyClass") .def("printThis", &MyClass::printThis) ; } void exec_test() { std::cout << "registering extension module embedded_hello..." << std::endl; // Register the module with the interpreter if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1) throw std::runtime_error("Failed to add embedded_hello to the interpreter's " "builtin modules"); std::cout << "defining Python class derived from Base..." << std::endl; // Retrieve the main module python::object main = python::import("__main__"); // Retrieve the main module's namespace python::object global(main.attr("__dict__")); // Define the derived class in Python. python::object result = python::exec( "from embedded_hello import * \n" "class PythonDerived(Base): \n" " def hello(self): \n" " return 'Hello from Python!' \n" " def printMyClass(self, myObj): \n" " myObj.printThis() \n" , global, global); python::object PythonDerived = global["PythonDerived"]; MyClass myObj; // Creating and using instances of the C++ class is as easy as always. CppDerived cpp; BOOST_TEST(cpp.hello() == "Hello from C++!"); cpp.printMyClass(myObj); std::cout << "testing derived class from C++..." << std::endl; // But now creating and using instances of the Python class is almost // as easy! python::object py_base = PythonDerived(); Base& py = python::extract<Base&>(py_base) BOOST_EXTRACT_WORKAROUND; // Make sure the right 'hello' method is called. BOOST_TEST(py.hello() == "Hello from Python!"); py.printMyClass(myObj); std::cout << "success!" << std::endl; } void exec_file_test(std::string const &script) { std::cout << "running file " << script << "..." << std::endl; // Run a python script in an empty environment. python::dict global; python::object result = python::exec_file(script.c_str(), global, global); // Extract an object the script stored in the global dictionary. BOOST_TEST(python::extract<int>(global["number"]) == 42); std::cout << "success!" << std::endl; } void exec_test_error() { std::cout << "intentionally causing a python exception..." << std::endl; // Execute a statement that raises a python exception. python::dict global; python::object result = python::exec("print unknown \n", global, global); std::cout << "Oops! This statement should be skipped due to an exception" << std::endl; } int main(int argc, char **argv) { //BOOST_TEST(argc == 2); //std::string script = argv[1]; // Initialize the interpreter Py_Initialize(); bool error_expected = false; if ( python::handle_exception(exec_test) ) { if (PyErr_Occurred()) { if (!error_expected) BOOST_ERROR("Python Error detected"); PyErr_Print(); } else { BOOST_ERROR("A C++ exception was thrown for which " "there was no exception translator registered."); } } std::cin.get(); // Boost.Python doesn't support Py_Finalize yet, so don't call it! return boost::report_errors(); }