Python 调用 C 语言的简单流程(二)

本文揭示了在Python调用C语言编译的DLL时,由于C++的名称修饰导致的AttributeError问题。通过加入`extern "C"`声明或者使用Python的getattr函数和dll对象的顺序特性,可以解决函数名找不到的问题。文中提供了具体实例和相关参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python 调用 C 语言的简单流程(一)中,介绍了非常简单的建立DLL项目和用Python调用dll文件的流程,现在把这个技术应用到实践的时候,可能会碰到这样的问题:“AttributeError: function '****' not found”这是为什么呢?
现在假设在一个文件中有这样两个函数:
// Header
extern "C"
{ // Name in DLL will be "MyAdd" - but you won't be able to find parameters etc...
__declspec(dllexport) int MyAdd(int a, int b); 
} 

// Name will be with lot of prefixes but some other info is provided - IMHO better approach
__declspec(dllexport) int MyAdd2(int a, int b);


//.cpp Code
__declspec(dllexport) int MyAdd(int a, int b)
{ return a+b;
}
__declspec(dllexport) int MyAdd2(int a, int b)
{ return a+b;
} 

你感觉两个相同的函数,就差了一个extern"C"声明,这会有区别吗,这会导致你的Python调用dll的程序出错吗?答案就是:这正是导致AttributerError的元凶!

举个例子:

在C++的文件中函数生成的dll文件对应的导出名字是这个样子的:


然而C文件中函数生成的dll文件对应的导出名字却是这个样子:

### Python 调用 C 语言接口的方法与示例 在 Python调用 C 语言接口通常通过 `ctypes` 或其他工具来完成。以下是具体方法及其示例: #### 使用 `ctypes` 调用动态链接库中的 C 函数 `ctypes` 是 Python 的标准库之一,用于加载共享对象文件并调用其中定义的函数。下面是一个典型的例子。 假设有一个名为 `adder.c` 的 C 文件,其功能是计算两个整数或浮点数之和[^5]。 ```c /* filename: adder.c */ #include <stdio.h> __declspec(dllexport) int add_int(int n1, int n2){ return n1 + n2; } __declspec(dllexport) float add_float(float f1, float f2){ return f1 + f2; } ``` 编译该文件生成 `.dll`(Windows 平台)或 `.so`(Unix/Linux 平台)。例如,在 Linux 上可以运行以下命令: ```bash gcc -fPIC -shared adder.c -o adder.so ``` 接着编写对应的 Python 脚本来调用这些函数[^3]: ```python from ctypes import c_float, cdll # 加载共享对象文件 adder = cdll.LoadLibrary('./adder.so') # 调用加法函数 (int 版本) result_int = adder.add_int(4, 5) print(f"Sum of 4 and 5 = {result_int}") # 调用加法函数 (float 版本) adder.add_float.restype = c_float # 设置返回类型为 float a, b = c_float(5.5), c_float(4.1) result_float = adder.add_float(a, b) print(f"Sum of 5.5 and 4.1 = {result_float.value}") ``` 此代码展示了如何利用 `ctypes` 来访问由 C 实现的功能模块,并将其无缝集成到 Python 程序中[^5]。 #### 动态链接库的跨平台支持 需要注意的是,不同操作系统下使用的扩展名有所不同: - **Linux/Unix**: 扩展名为 `.so`; - **Windows**: 扩展名为 `.dll`; 因此,在实际应用时需根据目标环境调整路径设置[^3]。 --- #### 完整流程概述 为了成功实现 Python 对 C 接口的调用,一般遵循以下几个环节的操作指南[^4]: 1. 编写所需的 C 源码并导出必要的符号供外部程序使用。 2. 将源码编译为目标系统的动态链接库形式。 3. 利用 Python 提供的相关机制导入已构建好的库资源。 4. 配置参数传递规则以及指定预期的结果数据类型。 以上步骤构成了从零开始搭建整个框架的基础架构设计思路[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值