On 06/23/2009 04:43 PM, Christopher Schramm wrote:
Stefan Seefeld wrote:
You need a module into which to inject the symbols you export. That is
true no matter the (meta)type of what you export, i.e. classes,
functions, etc.
Once you have that module set up (via BOOST_PYTHON_MODULE), you can
instantiate the newly created Python objects (types) from within C++
code, without having to go through the interpreter, import, eval, or exec.
So you say I may use BOOST_PYTHON_MODULE to define a module and then
immediately work with it? Hm - I failed with that at my very first try.
What I did was using BOOST_PYTHON_MODULE and after that calling bpy's
import() to add it to my global namespace what failed due to not finding
the module.
An alternative is not to use BOOST_PYTHON_MODULE at all, but set up
converters in ordinary C++ code. In the following I set up a Python
interpreter in my main application, inject a (C++) base class, run a
Python script that adds a derived class, then instantiate and run that
derived class from C++ code. I this may just be what you want:
------------------------------
namespace bpl = boost::python;
// An abstract base class
class Base : public boost::noncopyable
{
public:
virtual ~Base() {};
virtual std::string hello() = 0;
};
// Familiar Boost.Python wrapper class for Base
struct BaseWrap : Base, bpl::wrapper<Base>
{
virtual std::string hello()
{
return this->get_override("hello")();
}
};
int main(int, char **)
{
Py_Initialize();
// Install C++ <-> Python converters
bpl::class_<BaseWrap, boost::noncopyable> base("Base");
// Retrieve the main module
bpl::object main = bpl::import("__main__");
// Retrieve the main module's namespace
bpl::object global(main.attr("__dict__"));
// Inject 'Base' type into global dict
global["Base"] = base;
try
{
// Run script
bpl::exec_file("exec.py", global, global);
// Extract 'Derived' class, and instantiate it
bpl::object derived = global["Derived"]();
// Extract reference-to-base-class
Base &d = bpl::extract<Base &>(derived);
// Call 'hello'
std::cout << d.hello() << std::endl;
}
catch (bpl::error_already_set const &)
{
PyErr_Print();
}
}
------------------------------
And the Python side:
------------------------------
class Derived(Base):
def hello(self): return 'Hello from Python !'
------------------------------
Easy, isn't it ?
Regards,
Stefan
--
...ich hab' noch einen Koffer in Berlin...
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig