使用pybind11,嵌入解释器并从C调用Python函数相对容易。但是,我不知道如何将Python成员函数添加到C类中。
到目前为止我所尝试的:
- 创建一个C++类
HelloWorld
- 创建 Package 此类的
PYBIND11_EMBEDDED_MODULE
- 在Python模块中导入此模块,该模块将向
HelloWorld
添加成员函数 - 将该模块导入
HelloWorld
本身
在C++方面,我有:
class HelloWorld
{
public:
void run() const
{
py::scoped_interpreter guard{};
auto backend = py::module_::import("backend");
// TODO: call HelloWorld._run()
}
char const *msg() const
{ return "Hello, World!"; }
};
PYBIND11_EMBEDDED_MODULE(frontend, m)
{
py::class_<HelloWorld>(m, "HelloWorld")
.def_static("msg", &HelloWorld::msg);
}
在Python方面(backend.py
)
from frontend import HelloWorld
HelloWorld._run = lambda self: print(self.msg())
但是我现在如何从C调用HelloWorld._run
呢?这个设置有意义吗?这个想法是用不同的Python后端扩展现有的C,这些后端可以快速组合在一起并在运行时交换。
1条答案
按热度按时间dphi5xsq1#
传递@maxy的回调是一个很好的建议。你的原始代码结构可能在原则上是有意义的,但你试图向编译的C代码添加一个成员函数,这实际上并不起作用。这只能在运行时发生,并且是一种有效的方法,但不是作为成员函数。
观察者模式是一种设计模式,用于:https://sourcemaking.com/design_patterns/observer/cpp/3
通过这种方式,你可以维护一系列已经在Python中实现的回调(类似于添加成员函数),但随后从C调用。本质上,你只是将函数指针传递给PyBind 11,所以有一个看起来像这样的绑定:
另一种方法是将Qt框架集成到您的解决方案中。https://www.qt.io/product/framework
Qt有一个“元对象编译器”,它允许你使用“信号”和“插槽”来实现观察者模式,而不需要上面描述的样板代码。你可以为
QObject::connect
创建一个绑定,然后将你的python定义的函数添加到你的C++类中。