python调用C++代码例子

my_module.cpp

#define PY_SSIZE_T_CLEAN
#define BOOST_PYTHON_MODULE_NAME my_module
//#include <pybind11/pybind11.h>
#include <boost/python.hpp>

int add(int a, int b) {
    return a + b;
}

//PYBIND11_MODULE(libmy_module, m) {
//    m.def("add", &add, "Prints a greeting from C++");
//}

BOOST_PYTHON_MODULE(libmy_module) {
    using namespace boost::python;
    def("add", add);
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.12)
project(kalibr-example)

# 查找 Boost.Python
find_package(Boost REQUIRED COMPONENTS python)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})

set(Python_ADDITIONAL_VERSIONS 3.11)  # 替换为您的 Python 版本
find_package(PythonLibs REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
#
#set(pybind11_DIR /home/local/.local/lib/python3.8/site-packages/pybind11/share/cmake/pybind11/)
#find_package(pybind11 REQUIRED)

add_library(my_module MODULE my_module.cpp)
#target_link_libraries(my_module PRIVATE pybind11::module)
target_link_libraries(my_module PRIVATE Boost::python)

python :main.py

import sys
import libmy_module
result = libmy_module.add(1, 2)
print ("result:{}".format(result))

出现的一个报错:

原因分析:

cmake生成的动态库名字为libmy_module.so

要和cpp代码中红框处的变量名保持一致才行

Boost.Python和pybind11区别

Boost.Python和pybind11都是用于在C++和Python之间进行绑定的工具,它们有一些区别和特点:

  1. 依赖性: Boost.Python是Boost库的一部分,因此使用Boost.Python需要安装和配置Boost库。而pybind11是一个独立的库,没有额外的依赖项,更容易使用和集成到项目中。

  2. 代码复杂性: Boost.Python在绑定C++和Python之间的交互时,使用了大量的宏和模板代码。这些代码可以让绑定变得更复杂,尤其对于大型项目来说。而pybind11使用更现代的C++特性,如类型推断和Lambda函数,使代码更简洁和易读。

  3. 性能: pybind11在性能方面通常比Boost.Python更好,因为pybind11使用了更优化的Python/C++ API调用和类型转换机制,同时也提供了更好的内存管理和异常处理。

  4. 语法风格: Boost.Python使用了一种更传统的C++风格的语法,包括宏定义和模板元编程。而pybind11使用了更现代的C++特性,如类型推断和Lambda函数,更接近于原生的C++编程风格。

总体而言,pybind11是一个相对较新、更简单和更高效的C++和Python绑定库,而Boost.Python则是一个更成熟和功能丰富的库。选择使用哪个库取决于项目的需求、开发团队的偏好以及与其他依赖项的集成等因素。

### 在 Python调用 C++ 函数或类 #### 使用 `ctypes` 调用 C++ 动态库 (DLL) 为了使 `ctypes` 成功加载并调用 C++ 编写的动态链接库中的函数,需先将 C++ 代码编译为兼容的 DLL 文件,并导出所需的函数。由于 C++ 名称修饰问题,通常建议在 C++ 头文件中使用 extern "C" 来防止名称被修改。 ```cpp // mylib.cpp extern "C" { __declspec(dllexport) int add(int a, int b){ return a + b; } } ``` 接着,在 Python 环境下可以通过如下方式加载此 DLL 并调用其中定义的功能: ```python from ctypes import cdll # 加载 dll 文件 dll = cdll.LoadLibrary(&#39;mylib.dll&#39;) # 调用加法函数 result = dll.add(3, 4) print(f"The result is {result}") ``` 需要注意的是,当处理更复杂的 C++ 类型时(比如对象实例化),则可能需要额外的工作来适配数据结构以及管理内存分配等问题[^4]。 #### 使用 `cffi` 实现更高层次的封装 相比于 `ctypes`,`cffi` 提供了一个更加直观的方式来进行 C/C++ 接口描述。对于简单的例子来说,可以直接在线解析源码字符串;而对于大型项目,则可以从头文件自动生成绑定代码。 下面给出一个简单案例说明如何利用 `cffi` 访问上述相同的 C++ 函数: ```python import cffi ffibuilder = cffi.FFI() # 定义接口声明 ffibuilder.cdef(""" int add(int a, int b); """) # 设置要构建的目标平台上的共享库路径 if sys.platform.startswith(&#39;win&#39;): ffibuilder.set_source("_mylib", r&#39;#include "mylib.h"&#39;, libraries=[&#39;mylib&#39;]) else: ffibuilder.set_source("_mylib", &#39;#include "mylib.h"&#39;, library_dirs=[&#39;.&#39;], runtime_library_dirs=[&#39;.&#39;]) # 构建扩展模块 ffibuilder.compile(verbose=True) # 导入生成的模块并测试功能 from _mylib import lib as mylib res = mylib.add(7, 8) print(f"CFFI Result: {res}") ``` 这种方法不仅简化了跨语言间的通信流程,而且允许开发者更容易地维护和更新底层实现细节而无需频繁更改高层逻辑[^3].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值