I have a C++ object and wish to pass it by reference/pointer to an embedded Python interpreter so that Python can make changes to it which are visible to both C++ and Python. I am using Boost.Python for interop.
For sake of example, here is a class Foo
, its Boost.Python wrapper, and a Foo
object in C++:
mymodule.h:
struct Foo
{
int bar;
Foo(int num): bar(num) {}
};
mymodule.cpp:
#include "mymodule.h"
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(mymodule)
{
using namespace boost::python;
class_<Foo>("Foo", init<int>())
.def_readwrite("bar", &Foo::bar)
;
}
main.cpp:
#include <iostream>
#include <boost/python.hpp>
#include "mymodule.h"
using namespace boost::python;
int main()
{
Py_Initialize();
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
import("mymodule");
Foo foo(42);
// ... somehow use Boost.Python to send reference to interpreter ...
object result = exec_file("myscript.py", main_namespace);
std::cout << foo.bar << std::endl;
}
So how do I send a reference of foo
to Python so both C++ and Python can see its contents?
In C++, prior to running the script, add:
main_namespace["foo"] = ptr(&foo);
Now the Python environment will have a pointer to the C++ variable foo
and any changes made to it by a Python script will be performed on the C++ object rather than a copy.
If myscript.py
is:
foo.bar = 12
then the output of the cout
line at the end will be 12
, not 42
.
Note that you may want to place foo
inside the mymodule
namespace to self-document its origin, i.e. mymodule.foo.bar
.
The Boost.Python documentation doesn't seem to describe this method of pass-by-pointer, but it works nonetheless.