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

1、官方文档:http://python.net/crew/theller/ctypes/tutorial.html

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

http://blog.csdn.net/magictong/article/details/3075478

3、聊聊Python ctypes 模块:

https://zhuanlan.zhihu.com/p/20152309

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

http://blog.csdn.net/linda1000/article/details/12623527

5、ctypes使用指南:

http://blog.csdn.net/samdy2008/article/details/52139142

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

把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返回)

<class '__main__.c_char_Array_20480'>

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

<cparam 'P' (02695C88)>

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

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

            for i in xrange(uwLenPara.value):

                f.write(my_array[i])

  

实验结果:

通过实例简介python使用ctypes模块调用C语言动态库的更多相关文章

  1. (转载)Python 的 JPype 模块调用 Jar 包

    Python 的 JPype 模块调用 Jar 包 背景与需求 最近学习并安装使用了HttpRunner框架去尝试做接口测试,并有后续在公司推广的打算. HttpRunner由Python开发,调用接 ...

  2. 关于C#调用非托管动态库方式的性能疑问

    最近的项目中,因为一些原因,需要C#调用非托管(这里为C++)的动态库.网上喜闻乐见的方式是采用静态(DllImport)方式进行调用.偶然在园子里看到可以用动态(LoadLibrary,GetPro ...

  3. C#调用C/C++动态库 封送结构体,结构体数组

    一. 结构体的传递 #define JNAAPI extern "C" __declspec(dllexport) // C方式导出函数 typedef struct { int ...

  4. Android NDK开发及调用标准linux动态库.so文件

    源:Android NDK开发及调用标准linux动态库.so文件 预备知识及环境搭建 1.NDK(native development Kit)原生开发工具包,用来快速开发C.C++动态库,并能自动 ...

  5. linux c编程调用系统的动态库时,要使用dlopen等函数吗?

    同问 linux c编程调用系统的动态库时,要使用dlopen等函数吗? 2012-11-27 21:55 提问者: hnwlxyzhl 我来帮他解答 满意回答 2012-12-07 09:08 li ...

  6. C#调用C/C++动态库,封装各种复杂结构体

    C#调用C/C++动态库,封装各种复杂结构体. 标签: c++结构内存typedefc# 2014-07-05 12:10 6571人阅读 评论(1) 收藏 举报  分类: C(8)  C#(6)  ...

  7. cpp调用c的动态库

    目录 cpp调用c的动态库 title: cpp调用c的动态库 date: 2019/11/22 20:34:29 toc: true --- cpp调用c的动态库 CPP文件里这么引用头文件即可 e ...

  8. Python多层目录模块调用

    一. 引用模块在 父+级目录中: 1. 将导入模块所在目录(../model/模块)添加到系统环境变量path下,可添加多个 import syssys.path.append("../mo ...

  9. python常见函数以及模块调用

    1.常用函数区别 print: 在python3.0中print是函数,这意味着需要编写print(A )而不是print A str()和repr()的区别 >>>print st ...

随机推荐

  1. 使用bitmap实现对一千万个无重复的正整数(范围1~1亿)快速排序

    1 Bytes(字节) == 8 bit 1 KBytes == 1024 Bytes 思路: 1)申请长度为1亿的保存二进制位的数组 a, 2)通过位运算,将整数做为索引,将数组a对应的索引位置为1 ...

  2. forEach、map、filter、reduce的区别

    1.相同点: 都会循环遍历数组中的每一项: map().forEach()和filter()方法里每次执行匿名函数都支持3个参数,参数分别是:当前元素.当前元素的索引.当前元素所属的数组: 匿名函数中 ...

  3. POJ 1182 食物链 (带权并查集 && 向量偏移)

    题意 : 中文题就不说题意了…… 分析 : 通过普通并查集的整理归类, 能够单纯地知道某些元素是否在同一个集合内.但是题目不仅只有种类之分, 还有种类之间的关系, 即同类以及吃与被吃, 而且重点是题目 ...

  4. PCL智能指针疑云 <二> 使用同一智能指针作为PCL预处理API的输入和输出

    问题介绍: slam构建地图,先进行降采样,再进行可视化或存储.然而经过降采样后,代码没有报错的情况下,点云数据散成一团.将代码和点云数据展示如下, pcl::VoxelGrid<Lidar:: ...

  5. Tree and Permutation

    Tree and Permutation 给出一个1,2,3...N的排列,显然全部共有N!种排列,每种排列的数字代表树上的一个结点,设Pi是其中第i种排列的相邻数字表示的结点的距离之和,让我们求su ...

  6. 接口自动化request库入门

    requests库7个主要方法 r= requsts.get(),主要属性: r.raise_for_status()方法内部判断r.status_code是否等于200不需要增加额外的if语句,该语 ...

  7. Java数据结构之排序---选择排序

    简单选择排序的介绍: 从给定的序列中,按照指定的规则选出某一个元素,再根据规定交换位置后达到有序的目的. 简单选择排序的基本思想: 假定我们的数组为int [] arr = new int[n],第一 ...

  8. 源码阅读-JLRoutes路由设置

    最后更新: 2018-1-20 JLRoutes 是在 github 上 Star 比较多的一个, 在各大平台也有介绍, 一些知识可以参考到下面的连接查看. 本文仅仅作为我的思考以及对应的心得; 一. ...

  9. 20175221 曾祥杰 数据库MySQL(课下作业,必做)

    数据库MySQL(课下作业,必做) 题目要求: 1. 下载附件中的world.sql.zip, 参考http://www.cnblogs.com/rocedu/p/6371315.html#SECDB ...

  10. 从三十而立的迷茫,到30K

    很标题党的标题,但是希望分享一下自己的经历,一份有点儿不寻常的经历. 12年创业,到17年末,举步维艰,没有项目,公司只剩下两个人,负债,现实给我这个每见过什么市面,却自命不凡的人狠狠的一个耳光.加上 ...