使用getattr调用缺少“Extern C” 的DLL

近日在调用一个厂家给的DLL库时,总是无法调用,后面经过多方百度,发现是因为DLL源码里缺了个“Extern C”(“Extern C”的作用是啥各位请移步度娘或者Google),导致DLL里面的函数名都经过了C++的修饰,只能供C++程序调用。哎我的天啊,自己写的脚本是Python,无法调用这个DLL,任务就完不成,绩效就没有,年终奖就打折了。。。似个愁啊。。。某夜,辗转入睡,梦中迷迷糊糊间貌似用了一个折中的方法,貌似还成功。激动得凌晨2~3点就睡不着了。第二天早上屁颠屁颠的试了下,居然成功,接下来,就让我细细讲解~~~

在调用DLL的时候,首先我们得先知道DLL里面都有哪些函数接口,正常的都会有一个文档来说明。一般来说,文档内的函数名和DLL内部的函数应该是一致的,这样才会方便调用者调用,但是,对于使用C++编写的DLL,如果缺少这个“Extern C”,编译链接时,C++会按照自己的规则篡改函数的名称,这会导致不同的编译器、不同的语言下调用dll发生问题。来看看我用到的这个DLL的文档源码头文件定义:

ARBNETZREMOTE_API int AddDataFile( unsigned int id, int layer, double delta, double voltage, double current );
ARBNETZREMOTE_API int AddDataFile( unsigned int id, int layer, double delta, double voltage, double current,int typ, double f1, double f2, double amp1, double amp2, double phi, int an ); 
ARBNETZREMOTE_API int AddDataFileVoltage( unsigned int id, double delta, double voltage );
ARBNETZREMOTE_API int AddDataFileCurrent( unsigned int id, double delta, double current );
ARBNETZREMOTE_API int ImportFile( unsigned int id, int layer, char* pName );
ARBNETZREMOTE_API int GetLayers(unsigned int id, int* layer);
ARBNETZREMOTE_API int GetLayersInfo(unsigned int id, int* layer, int* DataFile);

然后在使用工具查看实际的函数,如下:

可以看到,在DLL中,函数名里多了很多符号,这就导致我们在使用Ctypes调用里面的函数时,就没法根据函数名来进行调用了。因为这些函数名在python的语法中都是非法的。怎么办呢?咱们继续。

对了,在这里大家也看到了,首先还得看看DLL里面的函数名是啥。有很多工具,想visual studio的同学来说,可以直接使用dumpbin命令来查看,使用其他的可以使用dllexp,hap-depends来查看,在这里使用的是hap-depends。

接下来就要说到这个看起来平平无奇的函数了——getattr。没错,就是getattr,可以直接动态的调用实例中的属性。

完整的调用过程:

from ctypes import *
sibo = WinDLL('D:\PythonWorks\WaveMaster\WaveMaster_CPP_x64.dll')
openfile = getattr(sibo, '?OpenFile@@YAHPAIPAD@Z')

至此,上述代码中的openfile将具有DLL中OpenFile的所有属性了,openfile将成为一个Python可直接调用的函数API,当然了,调用格式还得按照ctypes的格式来使用。

要说的就这么多了,剩下的大家应该都懂了的。

(后面在仔细看看官方文档,发现里面居然也有这个注释~~~~捂脸仰天)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值