python调用C/C++动态库

本文以windows环境下的.dll动态链接库为背景展开,有关linux下的.so动态链接库的相关用法会在另外一篇文章中展开讲解。

1. 背景知识

一直以来python都被称为胶水语言,能够轻易地操作其他程序,轻易地包装使用其他语言编写的库。下面简单介绍下如何使用python来调用C/C++编写的动态库。首先了解下动态链接库及C/C++动态库的区别。

1.1 动态链接库

使用VS2017创建动态链接库DllDemo,代码如下:

//整型相加
 __declspec(dllexport) int addInt(int a, int b) 
{
	return a + b;
}
//浮点型相加
__declspec(dllexport) float addFloat(float a, float b) 
{
	return a + b;
}
//传递float指针类型参数
__declspec(dllexport) void changeFloat(float *a) 
{
	*a = 100.00;
}
//传递char指针类型参数,返回指针类型参数
__declspec(dllexport) char* pointCh(char *a) 
{
	return a;
}

使用dumpbin.exe工具,在cmd命令行使用

dumpbin.exe -exports DllDemo.dll

查看动态库的导出函数如下:
C++动态库的导出函数列表

从上图可以看出动态库导出了4个函数,与上面代码中的导出函数一致。但是函数名长得很奇怪,这是因为在编译链接时,C++会按照自己的规则篡改函数的名称,这一过程称为"名字改编",C++支持函数重载,就是在函数名字改编阶段记录下函数的相关参数信息。

C++标准并没有定义名字改编的标准,因此会导致不同编译器编译出来的动态库不能通用。

1.2 extern "C"作用

相比之下,C标准规定了名字改编的标准,extern "C"指示编译器在编译代码是按照C的标准进行编译。
在上述代码的每个函数名前都加上extern "C"关键字。

extern "C" __declspec(dllexport) int addInt(int a, int b) 
{
	return a + b;
}

extern "C" __declspec(dllexport) float addFloat(float a, float b) 
{
	return a + b;
}

extern "C" __declspec(dllexport) void changeFloat(float *a) 
{
	*a = 100.00;
}

extern "C" __declspec(dllexport) char* pointCh(char *a) 
{
	return a;
}

查看动态库的导出函数,可以看到导出的函数名和函数的定义是一致的。
C动态库的导出函数

如果extern "C"修饰的函数进行了重载,则会在编译时报错,因为C语言并不支持函数的重载。

1.3 动态链接库加载方式

1.3.1 隐式链接

隐式链接需要.dll .lib文件

#include <iostream>
#include <Windows.h>
using namespace std;

//隐式加载需要导入动态库的导入库
#pragma comment(lib, "../Debug/DllDemo.lib")

//dll中导出的函数通过直接声明或者包含头文件的方式
extern "C" _declspec(dllimport) int addInt(int a, int b);
extern "C" _declspec(dllimport) float addFloat(float a, float b);

int main()
{
    //调用动态库中的函数
	cout << addInt(1, 2) << endl;
	cout << addFloat(1.25, 2.25) << endl;
}

通过vs自带的工具lib,通过命令lib /list XXXX.lib,可以查看一个.lib文件是静态库还是导入库

1.3.2 显式链接

显式链接需要.dll, 需要事先知道导出函数的签名,不需要.lib和.h文件


                
  • 2
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值