python什么模块动态调用链接库_通过实例简介python使用ctypes模块调用C语言动态库...

看介绍python语言时,说它是胶水语言,可以调用其他语言。通过使用ctypes模块就可以调用C语言的动态库。下面先放上官方文档和几个比较好的博文。

2、Python调用windows下DLL详解- ctypes库的使用:

3、聊聊Python ctypes 模块:

4、Python的学习(三十二)---- ctypes库的使用整理

5、ctypes使用指南:

因为这个实例,自己也只是简单使用没有整明白,所以先把参考的几个文章列出来。

把C语言编译为动态链接库。Windows下动态链接库的扩展名是dll,Linux下是so,Mac OS X下是dylib。

Gcc编译出的动态库,python调用时,可以直接调用原型,不需要做特殊处理。

VS使用的编译器是MSVC,和g++编译出来的动态库,需要特珠声明才能被调用。因为编译出的函数名实际上不是本来的名字,这也是C++可以重载的原因,真实的函数名已经变了。

头文件中定义

#ifdef __cplusplus

extern "C" { //这个是必须有的

#endif

/*************************************

*函数功能:打开摄像头

不是函数接口,所以不需要特殊处理

*************************************/

INT8U BSP_CameraOpen(INT8U ucPort);

/*************************************

*函数功能:获取图像

因是接口,需要特殊处理

*************************************/

_declspec(dllexport) INT8U BSP_CameraGetPhoto(INT8U ucFormat,INT8U *pDataBuf,INT16U *pDataLen);

/*

拍照片初始化,即创建串口,打开摄像头,之后就可以直接操作读照片了。

因是接口,需要特殊处理

*/

_declspec(dllexport) int ComCamInit(void);

#ifdef __cplusplus

};

#endif

如不特殊处理,python加载库时不会报错,但是调用函数接口时,会抛出找不到函数的异常。(编译库时,函数名字变了嘛)

>>> import ctypes#导入ctypes库

>>> testdll = ctypes.CDLL(r"D:\project program\photo\VS_dll\photo_dll\photo_dll.dll")

>>> ret = testdll.ComCamInit() #调用库中的ComCamInit()函数,返回0说明返回成功了。

>>> ret

0

库里的BSP_CameraGetPhoto()函数,参数为INT8U *pDataBuf,INT16U *pDataLen,需要传入一个数组的指针,用于返回获取到的图片数据,和一个short类型的指针用于保存返回的长度。

所以要用到数组的映射和指针的映射,也就是C语言的数据类型转换为ctypes中的数据类型。

基本类型映射

>>>type_uchar_array_20k = ctypes.c_char * (20*1024) #创建一个20K的char型数组类型type_uchar_array_20k

>>> my_array = type_uchar_array_20k() #实例化生成这个20K的char型数组的对象

>>> uwlen = 0 #定义uwlen

>>> uwLenPara= ctypes.c_ushort(uwlen) #这里可以不使用uwlen,而使用0,这里是要告诉 uwLenPara 的类型和值

>>> ret = testdll.BSP_CameraGetPhoto(1,my_array,ctypes.byref(uwLenPara))

>>> ret

40459264

>>> help(ctypes.byref)

Help on built-in function byref in module _ctypes:

byref(...)

byref(C instance[, offset=0]) -> byref-object

Return a pointer lookalike to a C instance, only usable

as function argument

Byref关键字会这个这个对像的指针。

返回结果为40459264( 0x2695C00)

Python中返回的类型默认为int,而库里这个函数返回的类型是unsigned char所以需要指定返回类型,这里最低字节0x00说明返回成功了。

如果动态链接库中的C函数返回值不是int,需要在调用函数之前显式的告诉ctypes返回值的类型

testdll.BSP_CameraGetPhoto.restype = ctypes.c_ubyte

>>> ret = testdll.BSP_RearCommClose() #调用动态库关闭串口句柄

>>> my_array #数组对象

<__main__.c_char_Array_20480 object at 0x02695CB0>

>>> my_array.value #输出数组的值需要用循环,这里只显示四个字节(默认按int显示)

'\xff\xd8\xff\xdb'

>>> uwlen #说明返回值和uwlen 没关系,定义uwLenPara时只是使用了uwlen做为初始值

0

>>> uwLenPara #返回他的类型,和值 6592

c_short(6592)

>>> uwLenPara.value

6592

>>> type_uchar_array_20k #数组类型(比较my_array返回)

>>> ctypes.byref(uwLenPara) #返回一个指针(02695C88)

#把获取到的图片数据写到二进制文件里,

>>> with open(r"D:\test123.jpg",'wb') as f:

for i in xrange(uwLenPara.value):

f.write(my_array[i])

实验结果:

939327-20180202175321328-849062863.png

939327-20180202175335312-37549932.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值