首页 > 编程语言 >C++业务流程需要经常变更,想用Python来做流程脚本,和C++互相调用,有什么好的案例吗?

C++业务流程需要经常变更,想用Python来做流程脚本,和C++互相调用,有什么好的案例吗?

时间:2024-12-03 16:33:27浏览次数:14  
标签:调用 socket Python 业务流程 C++ pybind11 my

在现代软件开发中,将性能敏感的部分用 C++ 实现,动态变化的业务逻辑用 Python 编写是一种常见的做法。这种方法结合了 C++ 的高性能和 Python 的灵活性,适合需要频繁变更逻辑的场景,比如业务流程、规则引擎、数据处理等。以下是一些实现 C++ 和 Python 互相调用的常见方式和实际案例的建议:


1. 常见的 C++ 与 Python 交互方式

(1)嵌入 Python 到 C++(Python C API)

C++ 程序通过嵌入 Python 解释器来执行 Python 脚本。通过 Python C API,可以初始化 Python 解释器、加载脚本文件或模块,调用函数,并获取结果。

优点
  • 高效,直接调用 Python 内部接口。
  • 灵活,可以完全控制 Python 的执行环境。
缺点
  • 代码复杂,Python C API 使用较为繁琐。
  • 需要处理 Python 和 C++ 数据类型之间的转换。
示例代码
#include <Python.h>  // Python C API 头文件

int main() {
    // 初始化 Python 解释器
    Py_Initialize();

    // 加载 Python 脚本
    PyObject* pModule = PyImport_ImportModule("my_script");  // 加载 my_script.py
    if (!pModule) {
        PyErr_Print();
        return -1;
    }

    // 调用 Python 函数
    PyObject* pFunc = PyObject_GetAttrString(pModule, "my_function");  // 获取 my_function 函数
    if (pFunc && PyCallable_Check(pFunc)) {
        // 构造函数参数
        PyObject* pArgs = PyTuple_Pack(2, PyLong_FromLong(10), PyLong_FromLong(20));
        PyObject* pValue = PyObject_CallObject(pFunc, pArgs);  // 调用函数
        
        // 处理返回值
        if (pValue) {
            long result = PyLong_AsLong(pValue);  // 获取返回值
            printf("Result from Python: %ld\n", result);
            Py_DECREF(pValue);
        }
        Py_DECREF(pArgs);
    } else {
        PyErr_Print();
    }

    // 清理
    Py_DECREF(pFunc);
    Py_DECREF(pModule);

    // 关闭 Python 解释器
    Py_Finalize();

    return 0;
}

(2)使用 Python/C++ 通信框架(如 pybind11 或 Boost.Python)

① pybind11
  • 简介
    pybind11 是一个现代化的 C++11/14/17 库,专门用于在 C++ 和 Python 之间进行绑定。
  • 优点
    • 代码简洁,易于使用。
    • 支持现代 C++ 特性,例如类型推导和智能指针。
    • 支持 Python 函数调用、C++ 函数/类暴露给 Python 等。
  • 缺点
    • 需要额外的库支持。
    • 性能可能略低于直接使用 Python C API。
示例代码
#include <pybind11/pybind11.h>

namespace py = pybind11;

// C++ 函数
int add(int a, int b) {
    return a + b;
}

// 暴露给 Python
PYBIND11_MODULE(my_module, m) {
    m.def("add", &add, "A function that adds two numbers");
}
  • 编译生成 Python 模块:
    c++ -O3 -Wall -shared -std=c++17 -fPIC `python3 -m pybind11 --includes` my_module.cpp -o my_module`python3-config --extension-suffix`
    
  • Python 调用:
    import my_module
    result = my_module.add(10, 20)
    print(f"Result from C++: {result}")
    
② Boost.Python
  • 简介
    Boost.Python 是 Boost 库的一部分,提供了强大的 Python 和 C++ 互操作支持。
  • 优点
    • 功能全面,支持复杂数据结构。
  • 缺点
    • 编译依赖较重,配置复杂。
    • 相比 pybind11,代码冗长。

(3)通过 IPC 或 RPC 实现(如 ZeroMQ、gRPC)

这种方式通过进程间通信(IPC)或远程过程调用(RPC)实现 C++ 和 Python 的交互,适合分布式系统或异步调用场景。

优点
  • 解耦 C++ 和 Python,跨语言协作更灵活。
  • 支持分布式部署。
缺点
  • 通信开销较高。
  • 需要额外的通信框架。
示例:ZeroMQ
  1. 使用 C++ 实现服务端,通过 ZeroMQ 接收 Python 请求。
  2. 使用 Python 实现客户端,向 C++ 服务端发送任务请求。
  • C++ 服务端示例:
    #include <zmq.hpp>
    #include <string>
    #include <iostream>
    
    int main() {
        zmq::context_t context(1);
        zmq::socket_t socket(context, ZMQ_REP);
        socket.bind("tcp://*:5555");
    
        while (true) {
            zmq::message_t request;
            socket.recv(request);
    
            std::string msg = std::string(static_cast<char*>(request.data()), request.size());
            std::cout << "Received: " << msg << std::endl;
    
            zmq::message_t reply(5);
            memcpy(reply.data(), "World", 5);
            socket.send(reply);
        }
        return 0;
    }
    
  • Python 客户端示例:
    import zmq
    
    context = zmq.Context()
    socket = context.socket(zmq.REQ)
    socket.connect("tcp://localhost:5555")
    
    socket.send(b"Hello")
    message = socket.recv()
    print(f"Received reply: {message}")
    
其他框架
  • gRPC:用于跨语言的高性能 RPC 框架。
  • HTTP/REST:通过 RESTful API 设计,让 C++ 提供服务,Python 调用。

(4)使用文件或数据库作为中介

通过文件(如 JSON、XML)或数据库传递数据,C++ 和 Python 分别读写。这种方式适合批处理任务,但不适用于高实时性场景。


2. 实际案例分析

(1)游戏引擎

  • 游戏引擎(如 Unity 或 Unreal Engine)常用 C++ 实现核心渲染和物理引擎,用 Python 或 Lua 实现脚本和业务逻辑。
  • 示例:
    • 核心计算(如碰撞检测、图形绘制)用 C++ 实现。
    • 游戏规则、AI 逻辑(如 NPC 行为)用 Python 脚本实现,支持动态加载和修改。

(2)金融交易系统

  • 场景
    • C++ 实现高性能的交易撮合引擎。
    • Python 用于快速开发业务逻辑,如风控规则、策略交易。
  • 实现
    • C++ 使用 pybind11 暴露撮合功能。
    • Python 调用接口,实现动态策略调整。

(3)机器学习与深度学习

  • 场景
    • 训练阶段用 Python 编写(如 TensorFlow、PyTorch)。
    • 推理阶段用 C++ 实现高性能部署。
  • 实现
    • Python 训练模型,导出文件(如 ONNX 格式)。
    • C++ 加载模型进行推理。

(4)Web 服务

  • 场景
    • C++ 提供高性能计算服务(如视频转码)。
    • Python 实现业务流程和 API 层(如 Flask、FastAPI)。
  • 实现
    • Python 调用 C++ 的动态链接库,或通过 HTTP 调用 C++ 后端服务。

3. 总结与建议

选择方式

  1. 业务逻辑复杂、需要高性能调用
    • 推荐使用 pybind11Boost.Python,简单易用。
  2. 分布式、异步调用场景
    • 推荐使用 ZeroMQgRPC
  3. 简单任务或批处理场景
    • 使用文件或数据库作为中介。

开发建议

  • 尽可能封装 C++ 的功能,提供清晰的接口给 Python 调用。
  • 对于高性能需求,避免频繁的 C++/Python 互相调用,减少上下文切换开销。
  • 注意数据类型转换的成本,尽量减少复杂的数据结构传递。

通过上述方法和案例,你可以根据实际需求选择合适的实现方式,将 C++ 和 Python 的优势结合起来,实现性能与灵活性的平衡!

标签:调用,socket,Python,业务流程,C++,pybind11,my
From: https://blog.csdn.net/chenby186119/article/details/144185265

相关文章

  • Linux C++ 服务器端这条线怎么走?一年半能做出什么?
    选择LinuxC++服务器方向是一个非常好的发展路径,这条方向需要扎实的基础知识和实践能力,同时有着很大的发展空间。以下是一个完整的学习路线和一年半的规划,帮助你在毕业前掌握核心技能并积累项目经验。一、LinuxC++服务器方向的核心知识体系LinuxC++服务器端开发的核心......
  • c++ 环形队列(RingBuffer)
    环形缓冲区(CircularBuffer)与环形队列类似,是一种数据结构,支持在固定容量下的高效读写操作。相比队列,环形缓冲区通常允许覆盖旧数据,这在某些场景(如实时数据流、日志处理)中非常有用。实现步骤核心变量:缓冲区数组buffer[]:存储数据。读指针head:指向下一个读取的位置。写指......
  • Python Tkinter 模块
    Python支持多种图形界面的第三方库,包括TkQtwxWidgets…Python提供的Tkinter模块,就是TkGUI工具包的接口。TkinterTk是图形库,支持多种操作系统,使用Tcl语言开发;Tk会调用操作系统提供的本地GUI接口,完成最终的GUI。所以代码实现的只需要调用Tkin......
  • 一段奇怪的Python代码,ChatGPT的解释——Python默认参数的可变对象共享
    deffoo(a,b=[]):b.append(a)returnb​print(foo(1))print(foo(1))print(foo(1)) 这段代码会产生许多人可能意料之外的结果。以下是代码的行为以及背后的原因:代码行为deffoo(a,b=[]):#默认参数b是一个空列表b.append(a)#将a添加......
  • python函数参数传递是否比C语言更高效?——ChatGPT的回答
    Python的函数参数传递并不一定比C语言更高效,两者在效率上的差异主要取决于底层实现和具体的使用场景。以下是详细的比较:C语言参数传递效率按值传递(PassbyValue)是C中的默认方式:函数调用时,实参的值被复制到形参。这意味着函数内部的修改不会影响外部变量。C使用编译......
  • pyad(Python Active Directory)入门教程
    今年换了工作,需要比较频繁的操作AD域控,但是之前同事写的PS脚本比较不灵活(主要是我也不太会PS),然后就想能不能使用Python来编写一些自动化程序操作域控,便找到了pyad这个库。pyad是一个第三方Python库,用于管理MicrosoftActiveDirectory,可以将AD对象表示为Python对象(ADUser、ADGrou......
  • Python的变量作用域
    合法gcount=0defglobal_test():print(gcount)global_test()不合法,报错行:tmp=gcount+1gcount=0defglobal_test():tmp=gcount+1gcount=tmpprint(gcount)global_test()不合法gcount=0defglobal_test():gcount+......
  • python_Django---基础
    1.创建app终端:python3.xmanage.pystartapp app(名字)2.路由创建urls.py:导入函数:fromapp(app名)importviews创建路由:path("/index",views.index(函数名))3.HTML页面内容动态显示views.py:defindex(request):......
  • python logger 控制台,滚动文件
    defsetup_logger(logger_name,level=logging.INFO):logging.basicConfig(format='%(asctime)s-%(filename)s[line:%(lineno)d]-%(levelname)s:%(message)s',level=logging.DEBUG,filename='./l......
  • python毕设 基于JavaEE的民宿预订平台程序+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、选题背景随着旅游业的蓬勃发展,民宿作为一种新兴的住宿方式在国内外都受到了广泛关注。关于民宿预订平台的研究,现有研究主要以大型酒店预订平台......