(pybind)c++调用python/python调用c++

pybind通常是使用c++调用python文件,创建一个名为test_basic.py的文件,下面叙述调用步骤:

1.c++调用python:

def test_main():
    print("hello python.")
    
def test_func2(a):
    print(type(a))
    a.print()

2.python调用c++,其实原理就是c++调用python再hook回去cpp代码,传给python的参数是一个对象(可以是指针,对象也可以),对象内部包含这cpp的函数,在python层的方法里面,调用cpp的方法即可。

#include <pybind11/pybind11.h>
#include <pybind11/functional.h>

#include <pybind11/embed.h>

#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)

class A
{
public:
    A() {}
    double a;

    void print();
};

void A::print()
{

    printf("hello A.\n");
}

namespace py = pybind11;

PYBIND11_EMBEDDED_MODULE(embeded, module)
{
    py::class_<A> a(module, "A");
    a.def("print", &A::print);
}

int main()
{
    py::scoped_interpreter python;

    auto test = py::module::import("tests.test_basic");
    auto embeded = py::module::import("embeded");
    // auto func = test.attr("test_main");
    py::object result;
    // result = func();
    auto func2 = test.attr("test_func2");
    // auto a = new A();
    auto a = A();
    // auto func_a = []()
    // { printf("hello anonymous function.\n"); };
    a.a = 1.0;
    result = func2(a);
}```

### 使用 Pybind11 实现 C++ 调用 Python 为了实现 C++Python 的交互,Pybind11 提供了一个强大的框架来简化这一过程。通过 Pybind11 可以轻松地在 C++ 中嵌入并执行 Python 代码。 #### 初始化 Python 解释器 要在 C++ 程序中调用 Python 代码,首先需要初始化 Python 解释器: ```cpp #include <pybind11/embed.h> // everything needed for embedding namespace py = pybind11; int main() { py::scoped_interpreter guard{}; // Start the interpreter and keep it alive // ... rest of your program ... } ``` 这段代码会启动 Python 解析器,并保持其运行直到程序结束[^1]。 #### 执行简单的 Python 表达式 一旦解释器被成功初始化,就可以开始执行一些基本的 Python 命令或表达式: ```cpp py::print("Hello, World!"); // Prints "Hello, World!" from within C++ auto result = py::eval("6 * 7"); // Evaluates a simple expression std::cout << "The answer is " << result.cast<int>() << std::endl; ``` 这里展示了如何打印消息以及评估简单算术运算的结果。 #### 导入模块和函数 除了直接编写 Python 语句外,还可以导入现有的 Python 模块及其功能: ```cpp try { auto sys = py::module_::import("sys"); sys.attr("path").attr("append")("."); auto my_module = py::module_::import("my_module"); int sum_result = my_module.attr("add")(3, 4).cast<int>(); } catch (const py::error_already_set& e) { PyErr_Print(); } ``` 上述例子说明了怎样安全地处理可能发生的错误,并且动态加载外部定义的功能。 #### 定义回调机制 有时希望从 Python 函数接收返回值或将数据传递给它;这可以通过定义适当的封装类来完成: ```cpp class CallbackWrapper : public py::wrapper<CallbackInterface> { public: void callback_method(int value) override { PYBIND11_OVERRIDE_PURE( void, CallbackInterface, callback_method, value); } }; // Registering the wrapper with pybind11... PYBIND11_MODULE(example_extension, m) { py::class_<CallbackInterface>(m, "CallbackInterface") .def(py::init<>()) .def("callback_method", &CallbackInterface::callback_method); py::class_<CallbackWrapper, CallbackInterface>(m, "CallbackWrapper") .def(py::init<>()); } // Using the wrapped class in Python side... from example_extension import CallbackWrapper as CW cw_instance = CW() result = cw_instance.callback_method(42) ``` 此部分介绍了更复杂的场景——即当涉及到双向通信时应采取的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值