pybind11 与 C++ 绑定类和回调函数的交互
最编程
2024-07-15 09:19:03
...
代码结构
----3rdparty
------pybind11 # 存放 pybind11编译好后的文件夹
—build
------test.py # 测试文件
—include
------calculator.h # 计算器类
—src
------calculator.cpp
-------example.cpp # 绑定计算器类的例子
—CMakeLists.txt
pybind11 怎么安装可以另行搜索,或者留言,根据实际情况我会再写教程。
编译环境 centos7 64
calculator.h
#include<string>
#include<functional>
class calculator
{
public:
calculator();
~calculator();
double add(double a, double b);
double sub(double a, double b);
double mult(double a, double b);
double div(double a, double b);
void setName(std::string name);
std::string getName();
void registerCallBack(std::function<void(int)> &handler);
private:
std::string name;
std::function<void(int)> m_handler = nullptr;
};
calculator.cpp
#include<calculator.h>
calculator::calculator()
{
}
calculator::~calculator()
{
}
double calculator::add(double a, double b)
{
if (m_handler) {
m_handler(a + b);
}
return a + b;
};
double calculator::sub(double a, double b)
{
if (m_handler) {
m_handler(a - b);
}
return a - b;
};
double calculator::mult(double a, double b)
{
if (m_handler) {
m_handler(a * b);
}
return a * b;
};
double calculator::div(double a, double b)
{
if ((int)b == 0 ) {
if (m_handler) {
m_handler(0XFFFFFFFF);
}
return 0XFFFFFFFF;
}
if (m_handler) {
m_handler(a / b);
}
return a / b;
};
void calculator::setName(std::string name)
{
this->name = name;
}
std::string calculator::getName()
{
return this->name;
}
void calculator::registerCallBack(std::function<void(int)> &handler)
{
m_handler = handler;
}
example.cpp
#include <pybind11/pybind11.h>
#include <iostream>
#include <calculator.h>
#include <pybind11/stl.h>
#include <pybind11/complex.h>
#include <pybind11/functional.h>
#include <pybind11/chrono.h>
namespace py = pybind11;
int add(int i, int j) {
return i + j;
}
const char* helloworld()
{
return "hello world";
}
int h()
{
return 9999;
}
PYBIND11_MODULE(engine, m) {
m.doc() = "pybind11 engine plugin"; // optional module docstring
m.def("add", &add, "A function which adds two numbers");
m.def("hello", &helloworld, "hello world");
m.def("h9", &h, "h");
py::class_<calculator>(m, "calculator")
.def(py::init())
.def_property("name", &calculator::getName, &calculator::setName)
.def("setName", &calculator::setName)
.def("getName", &calculator::getName)
.def("add", &calculator::add)
.def("sub", &calculator::sub)
.def("mult", &calculator::mult)
.def("div", &calculator::div)
.def("registerCallBack", &calculator::registerCallBack);
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(pyCode)
set(CMAKE_CXX_STANDARD 11)
include_directories("include")
file(GLOB SRCS
src/example.cpp
src/calculator.cpp
)
add_subdirectory(3rdparty/pybind11)
pybind11_add_module(engine ${SRCS})
test.py
import engine;
def handle_message(value):
print("handle_message is ", value)
cc = engine.calculator()
cc.registerCallBack(handle_message)
while True:
a = float(input("plase input value: a:"))
b = float(input("plase input value: b:"))
cc.add(a, b)
cc.sub(a, b)
cc.div(a, b)
cc.mult(a, b)
编译:
cd build
cmake …
make -j
以上生成 engine.cpython-36m-x86_64-linux-gnu.so
执行:
总结:
pybind11 方便的实现了C++与python的交互,回调也不成问题,如果加上TCPIP等网络协议,就可以实现多进程多语言的交互,实现了多组件之间的通信。