'How to hold a Python object in C++ with PyBind11?
I'm using pybind11 to implement co-operation between Python and C++.
My target is that the main process is implemented with C++, and a Python interpreter is integrated into the c++ executable.
Most housekeeping logic is coded with C++, little high-level core logic will be coded with Python so as to rapidly change the algorithm.
I defined a virtual class named BaseClass in C++, and derive it in Python with a name DerivedClass, and then want to manage the life cycle of the objects in C++.
My question is How to dynamically create a Python object in C++, and hold it, and release it in C++? So far I can only get a BaseClass obj if I create a DerivedClass obj and assign it to a C++ variable.
The C++ codes:
#include <pybind11/embed.h>
#include <pybind11/pybind11.h>
#include <iomanip>
#include <iostream>
namespace py = pybind11;
using namespace py::literals;
class BaseClass {
public:
virtual ~BaseClass() { std::cout << "Destroy():" << std::hex << ",this:" << this << std::endl; };
BaseClass() { std::cout << "BaseClass():" << std::hex << ",this:" << this << std::endl; };
BaseClass( const BaseClass& o_ ) {
std::cout << "BaseClass() copying" << std::hex << ",this:" << this << ",from:" << &o_ << std::endl; };
BaseClass( BaseClass&& o_ ) {
std::cout << "BaseClass() moving" << std::hex << ",this:" << this << ",from:" << & o_ << std::endl; };
BaseClass& operator=( BaseClass&& o_ ) {
std::cout << "MovingAssignment" << std::hex << ",this:" << this << ",from:" << & o_ << std::endl;
return *this;
};
BaseClass& operator=( const BaseClass& o_ ) {
std::cout << "CopyingAssignment" << std::hex << ",this:" << this << ",from:" << & o_ << std::endl;
return *this;
};
virtual void showMe() {
std::cout << "show BaseClass" << std::hex << ",this:" << this << std::endl;
};
};
class BaseClassPy : public BaseClass {
using BaseClass::BaseClass;
void showMe() override {
PYBIND11_OVERRIDE(
void,
BaseClass,
showMe
);
};
};
PYBIND11_EMBEDDED_MODULE( ModuleEmbed, m ) {
py::class_<BaseClass, BaseClassPy>( m, "BaseClass" )
.def( py::init<>() )
.def( "showMe", &BaseClass::showMe );
};
int main() {
py::scoped_interpreter guard {};
auto mod_py = py::module_::import( "ModulePy" );
auto py_obj = mod_py.attr( "DerivedClass" )().cast<BaseClass>();
py_obj.showMe();
};
The Python code(file: ModulePy.py):
import ModuleEmbed
class DerivedClass( ModuleEmbed.BaseClass ):
def __init__( self ):
print( "DerivedClass() in Python" )
super().__init__()
def showMe( self ):
print( "show DerivedClass" )
The result output:
DerivedClass() in Python
BaseClass():,this:0x5631d27abc50
BaseClass() moving,this:0x7ffe43976010,from:0x5631d27abc50
Destroy():,this:0x5631d27abc50
show BaseClass,this:0x7ffe43976010
Destroy():,this:0x7ffe43976010
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
