embedding.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 155 行

CPP
155
字号
// 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;// An abstract base classclass Base : public boost::noncopyable{public:  virtual ~Base() {};  virtual std::string hello() = 0;};// C++ derived classclass CppDerived : public Base{public:  virtual ~CppDerived() {}  virtual std::string hello() { return "Hello from C++!";}};// Familiar Boost.Python wrapper class for Basestruct BaseWrap : Base, python::wrapper<Base>{  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#python.class_virtual_functions    return python::call<std::string>(this->get_override("hello").ptr());#else    return this->get_override("hello")();#endif  }};// Pack the Base class wrapper into a moduleBOOST_PYTHON_MODULE(embedded_hello){  python::class_<BaseWrap, boost::noncopyable> base("Base");}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",    global, global);  python::object PythonDerived = global["PythonDerived"];  // Creating and using instances of the C++ class is as easy as always.  CppDerived cpp;  BOOST_TEST(cpp.hello() == "Hello from C++!");  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!");  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)      || python::handle_exception(boost::bind(exec_file_test, script))      || (          (error_expected = true)          && python::handle_exception(exec_test_error)      )  )  {    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.");    }  }    // Boost.Python doesn't support Py_Finalize yet, so don't call it!  return boost::report_errors();}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?