Python 使用 ctypes 调用 C++ 共享库的方法

周予安
周予安
发布时间:2026-10-12| 4人浏览过
原创

本文详解如何利用 Python 内置模块 ctypes 加载 C++ 动态链接库。涵盖基础函数调用流程,重点演示如何通过内存指针实现 NumPy 数据的零拷贝交互,附带跨平台编译要点与运行报错排查指南。

Python 使用 ctypes 调用 C++ 共享库的核心步骤

第1步:编写 C++ 源码与头文件

为了使 Python 能够准确识别函数入口,C++ 代码必须使用 extern "C" 限制符包装,以防止编译器进行名称修饰(Name Mangling)。以简单的整数加法为例:

代码文件:add.cpp

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

头文件:add.h

extern "C"
int add(int a, int b);

第2步:编译生成动态链接库

在 Linux 或 macOS 环境下,使用 g++ 将上述源码编译为共享对象文件。命令如下:

$ g++ -fPIC -shared -o add.so add.cpp

参数说明:
- -fPIC:生成位置无关代码,是构建共享库的标准要求。
- -shared:指定输出为动态链接库格式。
- 若需传递 NumPy 数组,后续步骤中将编译对应的 add_arr.so。

第3步:在 Python 中加载并调用基础函数

使用 Python 标准库 ctypes 加载编译好的 .so 文件,并直接传递整型参数。代码如下:

from ctypes import cdll

lib = cdll.LoadLibrary('./add.so')
a = 5
b = 4
c = lib.add(a, b)
print("a + b = ", c)

执行后控制台将输出 a + b = 9。此时无需手动指定参数类型,ctypes 会默认匹配 C 风格的 int 传入。

第4步:传递 NumPy 数组的指针操作技巧

当需要处理大规模数据(如矩阵运算)时,直接拷贝数组会严重拖慢性能。正确的做法是将 NumPy 数组的底层内存地址作为指针传递给 C++,实现零拷贝交互。

C++ 实现(add_arr.cpp):

void add_arr(double a[10][10], double b[10][10], double c[10][10]) {
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            c[i][j] = a[i][j] + b[i][j];
        }
    }
}

对应头文件(add_arr.h):

extern "C"
void add_arr(double a[10][10], double b[10][10], double c[10][10]);

Python 调用代码:

import numpy as np
from ctypes import cdll, POINTER, c_double

# 自定义辅助函数:将 NumPy 数组转为 ctypes 指针
def get_ptr(arr):
    return arr.ctypes.data_as(POINTER(c_double))

# 加载库并严格声明参数类型,防止隐式类型转换导致段错误
lib = cdll.LoadLibrary('./add_arr.so')
lib_add_arr = lib.add_arr
lib_add_arr.argtypes = [
    POINTER(c_double),
    POINTER(c_double),
    POINTER(c_double)
]

# 初始化测试数据(确保数据类型为 float64 以匹配 C++ double)
a = np.random.rand(10, 10).astype(np.float64)
b = np.random.rand(10, 10).astype(np.float64)
c = np.zeros((10, 10)).astype(np.float64)

# 传递指针执行计算
lib_add_arr(get_ptr(a), get_ptr(b), get_ptr(c))
print("Array calculation completed.")

在此流程中,.astype(np.float64) 确保内存布局连续且符合 C/C++ 的 double 标准,argtypes 强制类型检查提升稳定性。C++ 修改 c 数组的内容会直接反映在 Python 端的 c 变量中,从而实现高效的数据交换。

常见问题排错与注意事项

  • 找不到动态库:确保 .so 文件位于 Python 脚本同级目录,或已添加到系统环境变量 LD_LIBRARY_PATH 中。
  • 段错误(Segmentation Fault):通常由参数类型不匹配或数组越界引起。务必使用 argtypes 声明签名,并确保 NumPy 数组数据对齐为 float64/double,切勿传递含空值的非标量结构。
  • Windows 平台适配:Linux 使用 .so 后缀,Windows 需替换为 .dll,且编译命令应改用 MSVC 的 cl /DLL /Fe:add.dll add.cpp 或 MinGW-w64。

以上就是 Python 使用 ctypes 调用 C++ 方法的详细内容,更多关于 Python 跨语言编程与高性能计算的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。