mirror of
https://github.com/boostorg/python.git
synced 2026-01-26 18:52:26 +00:00
Add basic embedding support.
[SVN r30601]
This commit is contained in:
@@ -54,6 +54,8 @@ if [ check-python-config ]
|
||||
object_protocol.cpp
|
||||
object_operators.cpp
|
||||
wrapper.cpp
|
||||
exec.cpp
|
||||
import.cpp
|
||||
;
|
||||
|
||||
dll boost_python
|
||||
|
||||
88
doc/v2/exec.html
Normal file
88
doc/v2/exec.html
Normal file
@@ -0,0 +1,88 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - <boost/python/exec.hpp></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/exec.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#functions">Functions</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#exec-spec"><code>exec</code></a></dt>
|
||||
<dt><a href="#exec_file-spec"><code>exec_file</code></a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p>Exposes a mechanism for embedding the python interpreter into C++ code.</p>
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
|
||||
<h3><a name="exec-spec"></a><code>exec</code></h3>
|
||||
<pre>
|
||||
object exec(str code,
|
||||
object globals = object(),
|
||||
object locals = object());
|
||||
</pre>
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Effects:</b>
|
||||
Execute Python source code from <code>code</code> in the context
|
||||
specified by the dictionaries <code>globals</code> and <code>locals</code>.
|
||||
</dt>
|
||||
<dt><b>Returns:</b>
|
||||
An instance of <a href="object.html#object-spec">object</a>
|
||||
which holds the result of executing the code.
|
||||
</dt>
|
||||
</dl>
|
||||
|
||||
<h3><a name="exec_file-spec"></a><code>exec_file</code></h3>
|
||||
<pre>
|
||||
object exec_file(str filename,
|
||||
object globals = object(),
|
||||
object locals = object());
|
||||
</pre>
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Effects:</b>
|
||||
Execute Python source code from the file named by <code>filename</code>
|
||||
in the context specified by the dictionaries <code>globals</code> and
|
||||
<code>locals</code>.
|
||||
</dt>
|
||||
<dt><b>Returns:</b>
|
||||
An instance of <a href="object.html#object-spec">object</a>
|
||||
which holds the result of executing the code.
|
||||
</dt>
|
||||
</dl>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
62
doc/v2/import.html
Normal file
62
doc/v2/import.html
Normal file
@@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - <boost/python/import.hpp></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/import.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#functions">Functions</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#import-spec"><code>import</code></a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p>Exposes a mechanism for importing python modules.</p>
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
|
||||
<h3><a name="import-spec"></a><code>import</code></h3>
|
||||
<pre>
|
||||
object import(str name);
|
||||
</pre>
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Effects:</b> Imports the module named by <code>name</code>.</dt>
|
||||
<dt><b>Returns:</b> An instance of <a href="object.html#object-spec">object</a>
|
||||
which holds a reference to the imported module.</dt>
|
||||
</dl>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -60,6 +60,8 @@
|
||||
|
||||
<dt><a href="#type_conversion">To/From Python Type Conversion</a></dt>
|
||||
|
||||
<dt><a href="#embedding">Embedding</a></dt>
|
||||
|
||||
<dt><a href="#utility">Utility and Infrastructure</a></dt>
|
||||
|
||||
<dt><a href="#topics">Topics</a></dt>
|
||||
@@ -939,6 +941,39 @@
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="embedding">Embedding</a></h2>
|
||||
|
||||
<dl class="index">
|
||||
<dt><a href="exec.html">exec.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="exec.html#functions">Functions</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="exec.html#exec-spec">exec</a></dt>
|
||||
<dt><a href="exec.html#exec_file-spec">exec_file</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="import.html">import.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="import.html#functions">Functions</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="import.html#import-spec">import</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="utility">Utility and Infrastructure</a></h2>
|
||||
|
||||
<dl>
|
||||
|
||||
@@ -25,11 +25,13 @@
|
||||
# include <boost/python/enum.hpp>
|
||||
# include <boost/python/errors.hpp>
|
||||
# include <boost/python/exception_translator.hpp>
|
||||
# include <boost/python/exec.hpp>
|
||||
# include <boost/python/extract.hpp>
|
||||
# include <boost/python/handle.hpp>
|
||||
# include <boost/python/has_back_reference.hpp>
|
||||
# include <boost/python/implicit.hpp>
|
||||
# include <boost/python/init.hpp>
|
||||
# include <boost/python/import.hpp>
|
||||
# include <boost/python/instance_holder.hpp>
|
||||
# include <boost/python/iterator.hpp>
|
||||
# include <boost/python/list.hpp>
|
||||
|
||||
31
include/boost/python/exec.hpp
Normal file
31
include/boost/python/exec.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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)
|
||||
#ifndef EXEC_SS20050616_HPP
|
||||
# define EXEC_SS20050616_HPP
|
||||
|
||||
# include <boost/python/object.hpp>
|
||||
# include <boost/python/str.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace python
|
||||
{
|
||||
|
||||
// Execute python source code from str.
|
||||
// global and local are the global and local scopes respectively,
|
||||
// used during execution.
|
||||
object
|
||||
exec(str string, object global = object(), object local = object());
|
||||
|
||||
// Execute python source code from file filename.
|
||||
// global and local are the global and local scopes respectively,
|
||||
// used during execution.
|
||||
object
|
||||
exec_file(str filename, object global = object(), object local = object());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -22,6 +22,13 @@
|
||||
# include <boost/utility.hpp>
|
||||
# include <boost/call_traits.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(BOOST_INTEL_WIN, <= 900)
|
||||
// workaround for VC++ 6.x or 7.0
|
||||
# define BOOST_EXTRACT_WORKAROUND ()
|
||||
#else
|
||||
# define BOOST_EXTRACT_WORKAROUND
|
||||
#endif
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace api
|
||||
|
||||
22
include/boost/python/import.hpp
Normal file
22
include/boost/python/import.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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)
|
||||
#ifndef IMPORT_SS20050624_HPP
|
||||
# define IMPORT_SS20050624_HPP
|
||||
|
||||
# include <boost/python/object.hpp>
|
||||
# include <boost/python/str.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace python
|
||||
{
|
||||
|
||||
// Import the named module and return a reference to it.
|
||||
object import(str name);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
45
src/exec.cpp
Normal file
45
src/exec.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// 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/exec.hpp>
|
||||
#include <boost/python/borrowed.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace python
|
||||
{
|
||||
|
||||
object exec(str string, object global, object local)
|
||||
{
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *s = python::extract<char *>(string);
|
||||
PyObject* result = PyRun_String(s, Py_file_input, global.ptr(), local.ptr());
|
||||
if (!result) throw_error_already_set();
|
||||
return object(detail::new_reference(result));
|
||||
}
|
||||
|
||||
// Execute python source code from file filename.
|
||||
// global and local are the global and local scopes respectively,
|
||||
// used during execution.
|
||||
object exec_file(str filename, object global, object local)
|
||||
{
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *f = python::extract<char *>(filename);
|
||||
// Let python open the file to avoid potential binary incompatibilities.
|
||||
PyObject *pyfile = PyFile_FromString(f, "r");
|
||||
if (!pyfile) throw std::invalid_argument(std::string(f) + " : no such file");
|
||||
python::handle<> file(pyfile);
|
||||
PyObject* result = PyRun_File(PyFile_AsFile(file.get()),
|
||||
f,
|
||||
Py_file_input,
|
||||
global.ptr(), local.ptr());
|
||||
if (!result) throw_error_already_set();
|
||||
return object(detail::new_reference(result));
|
||||
}
|
||||
|
||||
} // namespace boost::python
|
||||
} // namespace boost
|
||||
25
src/import.cpp
Normal file
25
src/import.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
// 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/import.hpp>
|
||||
#include <boost/python/borrowed.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace python
|
||||
{
|
||||
|
||||
object import(str name)
|
||||
{
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *n = python::extract<char *>(name);
|
||||
python::handle<> module(python::borrowed(PyImport_AddModule(n)));
|
||||
return python::object(module);
|
||||
}
|
||||
|
||||
} // namespace boost::python
|
||||
} // namespace boost
|
||||
@@ -74,10 +74,10 @@ rule bpl-test ( name ? : files * : requirements * )
|
||||
|
||||
test-suite python
|
||||
:
|
||||
[
|
||||
run ../test/embedding.cpp <lib>../build/boost_python
|
||||
[
|
||||
run ../test/exec.cpp <lib>../build/boost_python
|
||||
: # program args
|
||||
: # input files
|
||||
: ../test/exec.py
|
||||
: # requirements
|
||||
$(PYTHON_PROPERTIES)
|
||||
<define>BOOST_PYTHON_STATIC_LIB
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// 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)
|
||||
|
||||
// embedded_hello -- A simple Boost.Python embedding example -- by
|
||||
// Dirk Gerrits
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
|
||||
namespace python = boost::python;
|
||||
|
||||
// An abstract base class
|
||||
class Base : public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
virtual ~Base() {};
|
||||
|
||||
virtual std::string hello() = 0;
|
||||
};
|
||||
|
||||
// C++ derived class
|
||||
class CppDerived : public Base
|
||||
{
|
||||
public:
|
||||
virtual ~CppDerived() {}
|
||||
|
||||
std::string hello()
|
||||
{
|
||||
return "Hello from C++!";
|
||||
}
|
||||
};
|
||||
|
||||
// Familiar Boost.Python wrapper class for Base
|
||||
struct BaseWrap : public Base
|
||||
{
|
||||
BaseWrap(PyObject* self_)
|
||||
: self(self_) {}
|
||||
|
||||
std::string hello() { return python::call_method<std::string>(self, "hello"); }
|
||||
|
||||
PyObject* self;
|
||||
};
|
||||
|
||||
// Pack the Base class wrapper into a module
|
||||
BOOST_PYTHON_MODULE(embedded_hello)
|
||||
{
|
||||
python::class_<Base, BaseWrap, boost::noncopyable>("Base")
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void test()
|
||||
{
|
||||
//- INITIALIZATION -----------------------------------------------------------//
|
||||
|
||||
// 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");
|
||||
// Retrieve the main module
|
||||
python::object main_module((
|
||||
python::handle<>(python::borrowed(PyImport_AddModule("__main__")))));
|
||||
|
||||
// Retrieve the main module's namespace
|
||||
python::object main_namespace((main_module.attr("__dict__")));
|
||||
|
||||
// Define the derived class in Python.
|
||||
// (You'll normally want to put this in a .py file.)
|
||||
python::handle<> result(
|
||||
PyRun_String(
|
||||
"from embedded_hello import * \n"
|
||||
"class PythonDerived(Base): \n"
|
||||
" def hello(self): \n"
|
||||
" return 'Hello from Python!' \n",
|
||||
Py_file_input, main_namespace.ptr(), main_namespace.ptr())
|
||||
);
|
||||
// Result is not needed
|
||||
result.reset();
|
||||
|
||||
// Extract the raw Python object representing the just defined derived class
|
||||
python::handle<> class_ptr(
|
||||
PyRun_String("PythonDerived\n", Py_eval_input,
|
||||
main_namespace.ptr(), main_namespace.ptr()) );
|
||||
|
||||
// Wrap the raw Python object in a Boost.Python object
|
||||
python::object PythonDerived(class_ptr);
|
||||
|
||||
//- MAIN PROGRAM -------------------------------------------------------------//
|
||||
|
||||
// Creating and using instances of the C++ class is as easy as always.
|
||||
CppDerived cpp;
|
||||
std::cout << cpp.hello() << 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)
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(BOOST_INTEL_WIN, <= 900)
|
||||
()
|
||||
#endif
|
||||
;
|
||||
std::cout << py.hello() << std::endl;
|
||||
}
|
||||
|
||||
void
|
||||
test_tutorial()
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
||||
object main_module((
|
||||
handle<>(borrowed(PyImport_AddModule("__main__")))));
|
||||
|
||||
object main_namespace = main_module.attr("__dict__");
|
||||
|
||||
handle<> ignored((PyRun_String(
|
||||
|
||||
"hello = file('hello.txt', 'w')\n"
|
||||
"hello.write('Hello world!')\n"
|
||||
"hello.close()"
|
||||
|
||||
, Py_file_input
|
||||
, main_namespace.ptr()
|
||||
, main_namespace.ptr())
|
||||
));
|
||||
}
|
||||
|
||||
void
|
||||
test_tutorial2()
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
||||
object main_module((
|
||||
handle<>(borrowed(PyImport_AddModule("__main__")))));
|
||||
|
||||
object main_namespace = main_module.attr("__dict__");
|
||||
|
||||
handle<> ignored((PyRun_String(
|
||||
|
||||
"result = 5 ** 2"
|
||||
|
||||
, Py_file_input
|
||||
, main_namespace.ptr()
|
||||
, main_namespace.ptr())
|
||||
));
|
||||
|
||||
int five_squared = extract<int>(main_namespace["result"]);
|
||||
assert(five_squared == 25);
|
||||
|
||||
object result((handle<>(
|
||||
PyRun_String("5 ** 2"
|
||||
, Py_eval_input
|
||||
, main_namespace.ptr()
|
||||
, main_namespace.ptr()))
|
||||
));
|
||||
|
||||
int five_squared2 = extract<int>(result);
|
||||
assert(five_squared2 == 25);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialize the interpreter
|
||||
Py_Initialize();
|
||||
|
||||
if (python::handle_exception(test))
|
||||
{
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Print();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (python::handle_exception(test_tutorial))
|
||||
{
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Print();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (python::handle_exception(test_tutorial2))
|
||||
{
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Print();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Boost.Python doesn't support Py_Finalize yet.
|
||||
// Py_Finalize();
|
||||
return 0;
|
||||
}
|
||||
#include "module_tail.cpp"
|
||||
138
test/exec.cpp
Normal file
138
test/exec.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
// 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 <iostream>
|
||||
|
||||
namespace python = boost::python;
|
||||
|
||||
// An abstract base class
|
||||
class Base : public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
virtual ~Base() {};
|
||||
virtual std::string hello() = 0;
|
||||
};
|
||||
|
||||
// C++ derived class
|
||||
class CppDerived : public Base
|
||||
{
|
||||
public:
|
||||
virtual ~CppDerived() {}
|
||||
virtual std::string hello() { return "Hello from C++!";}
|
||||
};
|
||||
|
||||
// Familiar Boost.Python wrapper class for Base
|
||||
struct 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 module
|
||||
BOOST_PYTHON_MODULE(embedded_hello)
|
||||
{
|
||||
python::class_<BaseWrap, boost::noncopyable> base("Base");
|
||||
}
|
||||
|
||||
|
||||
void exec_test()
|
||||
{
|
||||
// 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");
|
||||
// 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;
|
||||
std::cout << cpp.hello() << 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;
|
||||
std::cout << py.hello() << std::endl;
|
||||
}
|
||||
|
||||
void exec_file_test()
|
||||
{
|
||||
python::object main = python::import("__main__");
|
||||
python::dict global(main.attr("__dict__"));
|
||||
global.clear();
|
||||
python::object result = python::exec_file("exec.py", global, global);
|
||||
std::string global_as_string = python::extract<std::string>(python::str(global))
|
||||
BOOST_EXTRACT_WORKAROUND;
|
||||
std::cout << global_as_string << std::endl;
|
||||
}
|
||||
|
||||
void exec_test_error()
|
||||
{
|
||||
python::object main = python::import("__main__");
|
||||
python::dict global(main.attr("__dict__"));
|
||||
python::object result = python::exec("print unknown \n", global, global);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
bool success = true;
|
||||
// Initialize the interpreter
|
||||
Py_Initialize();
|
||||
|
||||
if (python::handle_exception(exec_test) ||
|
||||
python::handle_exception(exec_file_test))
|
||||
{
|
||||
if (PyErr_Occurred()) PyErr_Print();
|
||||
else
|
||||
{
|
||||
std::cerr << "A C++ exception was thrown for which "
|
||||
<< "there was no exception handler registered." << std::endl;
|
||||
}
|
||||
success = false;
|
||||
}
|
||||
if (python::handle_exception(exec_test_error))
|
||||
{
|
||||
if (PyErr_Occurred()) PyErr_Print();
|
||||
else
|
||||
{
|
||||
std::cerr << "A C++ exception was thrown for which "
|
||||
<< "there was no exception handler registered." << std::endl;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
else success = false;
|
||||
|
||||
// Boost.Python doesn't support Py_Finalize yet.
|
||||
// Py_Finalize();
|
||||
return success ? 0 : 1;
|
||||
}
|
||||
|
||||
// Including this file makes sure
|
||||
// that on Windows, any crashes (e.g. null pointer dereferences) invoke
|
||||
// the debugger immediately, rather than being translated into structured
|
||||
// exceptions that can interfere with debugging.
|
||||
#include "module_tail.cpp"
|
||||
2
test/exec.py
Normal file
2
test/exec.py
Normal file
@@ -0,0 +1,2 @@
|
||||
print 'Hello World !'
|
||||
number = 42
|
||||
Reference in New Issue
Block a user