当前位置: 首页 > ds >正文

(4)python开发经验

文章目录

      • 1 使用ctypes库调用
      • 2 使用pybind11


更多精彩内容
👉内容导航 👈
👉Qt开发 👈
👉python开发 👈

1 使用ctypes库调用

  • 说明:ctypes是一个Python内置的库,可以提供C兼容的数据类型,并允许调用动态链接库中的函数。它允许Python直接与C的共享库(.dll文件在Windows系统中,.so文件在Linux系统中)进行交互。
  • 优点:
    • 不需要编译Python扩展模块,使用简单。
    • 可以直接加载和调用C++编写的函数。
  • 缺点:
    • 性能上不如专门设计的Python-C++绑定。
    • 对C++代码的复杂性支持有限,仅适用于简单的函数调用。
    • 需要手动处理数据类型转换,容易出错。
环境说明
系统windows11
编译器msvc2017
python3

c++代码

  • test.h

    #ifndef TEST_H
    #define TEST_Hextern "C"  // 这里是关键,声明C接口,防止C++编译器对函数名进行修饰
    { // 导出函数声明,如果是gcc、mingw编译器则去掉 __declspec(dllexport)__declspec(dllexport) int add(int a, int b); 
    }    
    #endif /* TEST_H */
    
  • test.cpp

    #include "test.h"int add(int a, int b)
    {return a + b;
    }
    
  • CMakeLists.txt

    cmake_minimum_required(VERSION 3.15)project(test)set(SOURCE test.htest.cpp)add_library(${PROJECT_NAME} SHARED ${SOURCE}) # 设置为动态库
    
  • 编译后会生成test.lib、test.dll两个文件;

  • 如果使用mingw编译器编译会生成libtest.dll.a、libtest.dll两个文件,使用libtest.dll。

python调用dll

  • 将test.dll文件放到main.py所在路径下。

  • main.py

    from ctypes import cdlllib = cdll.LoadLibrary('./test.dll')
    # 判断是否加载成功
    if lib:print("加载成功")
    else:print("加载失败")# 调用简单函数
    result = lib.add(3, 5)
    print(result)  # 输出8
    

注意: __declspec(dllexport) 是MSVC编译器特有的关键词,用于Windows平台的DLL导出。如果你使用的是GCC编译器(通常在Linux或macOS上使用),则不需要使用 __declspec(dllexport)

2 使用pybind11

pybind11 是一个用于方便地将 C++ 代码绑定到 Python 的库,它使得在 Python 中调用 C++ 函数、使用 C++ 类和数据结构变得简单。以下是 pybind11 的一些优点和缺点:

优点:

  1. 简单易用:pybind11 的语法简洁,易于上手。它提供了一种直观的方式将 C++ 代码暴露给 Python,这样即使是没有太多经验的用户也能够快速地编写绑定代码。
  2. 高性能:由于 pybind11 直接将 C++ 的类型映射到 Python 的类型,它可以提供接近于直接调用 C++ 函数的性能。
  3. 良好的 ABI 支持:pybind11 可以很好地处理 Python 的 ABI(Application Binary Interface),这意味着它在不同的 Python 版本之间具有很好的兼容性。
  4. 支持复杂的 C++ 特性:除了基本的数据类型之外,pybind11 还支持复杂的 C++ 特性,如 STL 容器、智能指针、异常处理等。
  5. 自动类型转换:pybind11 提供了自动的类型转换机制,使得在 C++ 和 Python 之间传递数据变得更加容易。

缺点:

  1. 学习曲线:虽然 pybind11 的语法简单,但要充分利用它的功能,还需要对 C++ 和 Python 的一些底层机制有一定的了解,这可能会形成一定的学习曲线。
  2. 调试复杂:当绑定的 C++ 代码出现问题时,调试可能会变得复杂,因为错误信息可能只出现在 Python 端,而实际的错误可能在 C++ 代码中。
  3. 跨平台一致性:虽然 pybind11 旨在提供跨平台的一致性,但在某些特殊情况下,可能仍然会遇到平台相关的兼容性问题。
  4. 依赖于 CMake:pybind11 建议使用 CMake 来构建项目,这对于那些不熟悉 CMake 的开发者来说可能会增加一些额外的负担。
  5. 编译时间:对于大型项目,编译时间可能会比较长,这取决于项目的复杂度和规模。
环境说明
系统windows11
编译器msvc2017-64
注意:如果使用mingw编译则python可能无法使用,python一般是使用msvc生成
  • 使用git clone https://github.com/pybind/pybind11.git下载源码;

  • 将pybind11文件夹放到C++工程路径下;

    在这里插入图片描述

  • test.cpp

    #include <pybind11/pybind11.h>int add(int a, int b) {return a + b;
    }namespace py = pybind11; // 这里的命名空间别名是 pyPYBIND11_MODULE(test, m) {// def用法:def(name, function, doc_string)// name: 在Python中调用的函数名// function: 要绑定的C++函数// doc_string: 函数的文档字符串m.def("add", &add, "A function which adds two numbers");
    }
  • CMakeLists.txt

    cmake_minimum_required(VERSION 3.15)project(test)add_subdirectory(./pybind11) # 这里是添加pybind11的子目录set(SOURCE test.cpp)pybind11_add_module(${PROJECT_NAME} ${SOURCE}) # 使用pybind11_add_module函数生成模块
  • 编译后会生成一个test.cp313-win_amd64.pyd文件,将test.cp313-win_amd64.pyd放到main.py路径下。

  • main.py

    import testprint(test.add(2,3))
    
  • 或者使用pip install pybind11安装库;

  • CMakeLists.txt如下所示:

    cmake_minimum_required(VERSION 3.15)project(test)# 寻找python库,Interpreter:表示查找 Python 解释器,Development:表示查找 Python 开发包
    find_package(Python COMPONENTS Interpreter Development) 
    # 查找pybind11包,并设置路径
    find_package(pybind11 PATHS "E:/py/PythonProject1/.venv/Lib/site-packages/pybind11/share/cmake/" REQUIRED) set(SOURCE test.cpp)pybind11_add_module(${PROJECT_NAME} ${SOURCE}) # 使用pybind11_add_module函数生成模块


http://www.xdnf.cn/news/6306.html

相关文章:

  • (十七)Java日期时间API全面解析:从传统Date到现代时间处理
  • Ros2 - Moveit2 - DeepGrasp(深度抓握)
  • golang -- 如何让main goroutine等一等
  • 数智驱动——AI:企业数字化转型的“超级引擎”
  • FreeRTOS学习笔记
  • 【Java学习笔记】finalize方法
  • 前后端分离博客 Weblog 项目实战
  • 【AI大模型】赋能【传统业务】
  • Java基础语法之数组
  • Windows下Docker安装portainer
  • 64. 最小路径和
  • Shell 脚本中的通道号(文件描述符)
  • maven项目, idea右上角一直显示gradle的同步标识, 如何去掉
  • 计算机网络:什么是计算机网络?它的定义和组成是什么?
  • 开源Heygem本地跑AI数字人视频教程
  • python使用matplotlib画图
  • IDEA编辑器设置的导出导入
  • why FPGA喜欢FMC子卡?
  • Vue3学习(组合式API——计算属性computed详解)
  • 使用Word2Vec算法实现古诗自动生成实战
  • Linux514 rsync 解决方案环境配置
  • 2025年渗透测试面试题总结-360[实习]安全工程师(题目+回答)
  • 三维CAD皇冠CAD(CrownCAD)建模教程:工程图模块二
  • 52页PPT | 企业数字化转型L1-L5数据架构设计方法论及案例数字化转型解决方案数字化规划方案
  • 回溯实战篇2
  • 今日行情明日机会——20250514
  • day25-异常处理
  • [Java实战]Spring Security 添加验证码(二十三)
  • android实现USB通讯
  • 基于 Kubernetes 部署容器平台kubesphere