2019独角兽企业重金招聘Python工程师标准>>>

版权声明:本文为博主原创文章,未经博主允许不得转载。

Python中ctypes的使用整理

ctypes是Python的一个外部库,提供和C语言兼容的数据类型,可以很方便地调用C DLL中的函数。ctypes的官方文档在这里。

1. ctypes基本数据类型映射表

参数类型预先设定好,或者在调用函数时再把参数转成相应的c_***类型。ctypes的类型对应如下:

ctypes type C type Python Type
c_char char 1-character string
c_wchar wchar_t 1-character unicode string
c_byte char int/long
c_ubyte unsigned char int/long
c_bool bool bool
c_short short int/long
c_ushort unsigned short int/long
c_int int int/long
c_uint unsigned int int/long
c_long long int/long
c_ulong unsigned long int/long
c_longlong __int64 or longlong int/long
c_ulonglong unsigned __int64 or unsigned long long int/long
c_float float float
c_double double float
c_longdouble long double float float
c_char_p char * string or None
c_wchar_p wchar_t * unicode or None
c_void_p void * int/long or None
     

对应的指针类型是在后面加上"_p",如int*是c_int_p等等。在python中要实现c语言中的结构,需要用到类。

2. 加载DLL

访问dll,首先需引入ctypes库 
from ctypes import *

假设你已经有了一个的DLL(名字是add.dll),且该DLL有一个符合cdecl(这里强调调用约定是因为,stdcall调用约定和cdecl调用约定声明的导出函数,在使用python加载时使用的加载函数是不同的,后面会有说明)调用约定的导出函数Add。
stdcall调用约定:两种加载方式

Objdll = ctypes.windll.LoadLibrary("dllpath")
Objdll = ctypes.WinDLL("dllpath")    

cdecl调用约定:也有两种加载方式

Objdll = ctypes.cdll.LoadLibrary("dllpath")
Objdll = ctypes.CDLL("dllpath")    

其实windll和cdll分别是WinDLL类和CDll类的对象。

3. 调用DLL方法

加载dll后会返回一个DLL对象,使用其中的函数方法则相当于操作该对象的对应属性。

注意,经过stdcall声明的方法,如果不是用def文件声明的导出函数或者extern “C” 声明的话,编译器会对函数名进行修改

函数参数申明,通过设置函数的argtypes属性

函数返回类型,函数默认返回c_int类型,如果需要返回其他类型,需要设置函数的restype属性

4. 指针与引用

常用的通过调用ctypes类型的指针函数来创建指针实例:

from ctype import *
i = c_int(1)
pi = POINTER(i)  

对指针实例赋值只会改变其指向的内存地址,而不是改变内存的内容,与其他语言类似,如需要可改变内容的字符串,可须使用create_string_buffer()

>>> p = create_string_buffer("Hello", 10)  # create a 10 byte buffer
>>> print sizeof(p), repr(p.raw)
10 'Hello/x00/x00/x00/x00/x00'  

不带参数的调用指针类型创建一个NULL指针, NULL指针有一个False布尔值

>>> null_ptr = POINTER(c_int)()
>>> print bool(null_ptr)
False   

指针实例有一个contents属性,返回这个指针所指向的对象。

另外,byref()是用来传递引用参数,pointer()作为传参通常会创建一个实际的指针对象,当不需要实际指针对象时,则可使用byref()

5. 结构体类型处理

Structures和Unions必须继承Structure和Union基础类,它们都在ctypes模块中定义,每一个子类必须定义个_fields_属性,_fields_是一个二维的tuples列表,包含着每个field的name及type,这field类型必须是一个ctypes类型,如c_int,或者任何其他的继承ctypes的类型,如Structure, Union, Array, 指针等。

例如有一个简单结构,包含两个整型x和y,可如下初始化一个结构:

from ctypes import *
import types
class Test(Structure):  _fields_ = [('x', c_int),  ('y', c_char)]
test1 = Test(1, 2)  

另外,如结构体用于链表操作,即包含指向结构体指针时,若直接定义:

from ctypes import *
import types
class Test(Structure):  _fields_ = [('x', c_int),  ('y', c_char),  ('next', Test)]  

则python会报错type未定义,:

from ctypes import *
import types
class Test(Structure):  pass
Test._fields_ = [('x', c_int),  ('y', c_char),  ('next', POINTER(Test))]  

6. 数组定义

数组包含一个固定数目的相同类型的实例,常用创建数组类型是对一个数据类型与一个正数相乘,例如:

ArrayType = Test * 10  
初始化和使用数组:  >>> from ctypes import *
>>> TenIntegers = c_int * 10
>>> ii = TenIntegers(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
>>> print ii
<c_long_Array_10 object at 0x...>
>>> for i in ii: print i,  

7. 回调函数

ctypes可以从python可调用对象中创建一个c可调用的函数指针,这些通常被称为回调函数。

(这个等用到时,再仔细研究。。。)

8、编译

Windows下动态链接库的扩展名是dll,Linux下是so,Mac OS X下是dylib。这里为了方便起见,一律将扩展名设定为dll。

Windows MSVC 下编译命令:(启动Visual Studio命令提示)

cl /LD great_module.c /o great_module.dll

Windows GCC、Linux、Mac OS X下编译命令相同:

gcc -fPIC -shared -msse4.2 great_module.c -o great_module.dll

写一个Python程序测试它,这个Python程序是跨平台的:

from ctypes import *
great_module = cdll.LoadLibrary('./great_module.dll')
print great_module.great_function(13)

转载于:https://my.oschina.net/mickelfeng/blog/1505196

ctypes库的使用整理相关推荐

  1. 【转】ctypes库的使用整理

    Python中ctypes的使用整理 ctypes是Python的一个外部库,提供和C语言兼容的数据类型,可以很方便地调用C DLL中的函数.ctypes的官方文档在这里. 1. ctypes基本数据 ...

  2. Python常用库 - 【持续整理归档】

    Python常用库 - [持续整理归档],比较多,会逐步慢慢细化分类和扩从python常用库.(最后更新:2020-4-8) 为方便Python开发人员进行敏捷开发,高效的完成工作需求,耗时很久整理的 ...

  3. python内置库之学习ctypes库(三)--调用Win32API

    ctypes库踩坑日记3 1.调用win32的api 2.最好让结构体和程序分开 3.取完数据找到对应信息,创建code.py 4.创建main.py,代码这样看着就很简洁 1.调用win32的api ...

  4. python内置库之学习ctypes库(二)

    ctypes库踩坑日记2 一.自己实现一个dll文件,再用python的ctypes库调用思路1更清晰 二.生成dll文件 三.ctypes库调用 一.自己实现一个dll文件,再用python的cty ...

  5. python内置库之学习ctypes库(一)

    ctypes库踩坑日记1 1.引言(这里是讲的windows下调用的方式) 2.结构体 3.联合体(共用体) 和上面结构体用法类似,只不过这里继承的是`Union`类 4.进阶用法 5.接受返回的值 ...

  6. python ctypes库中动态链接库加载方式

    最近看了<Gray hat python>一书,这才知道为什么python是黑客必学的编程语言.通过python的ctypes模块,可以直接调用动态链接库中的导出函数,而且甚至可以直接在p ...

  7. Python:使用ctypes库调用外部DLL 数据类型对应

    Python:使用ctypes库调用外部DLL(转) 前言

  8. python ctypes实现api测试_Python与C之间的相互调用(Python C API及Python ctypes库)

    2010-01-24 17:58 14237人阅读 评论(11) 我实现 Python C API 此部分可以参考我原来的文章< 准备工作: 闲话少说,看看Python C API.事实上,Py ...

  9. Python与C之间的相互调用(Python C API及Python ctypes库)

    2010-01-24 17:58 14237人阅读 评论(11) 收藏 举报 目录(?)[-] Python C API 准备工作: C中内嵌Python 获取返回值 利用C扩展Python Pyth ...

  10. c语言第一章考试题及答案,C语言考试题库及答案整理版.doc

    C语言考试题库及答案整理版.doc C语言理论上机考试选择题部分(共200题) 1.下面程序的输出是___D______ #include void main() { int k=11; printf ...

最新文章

  1. 349.两个数组的交集
  2. ListListObject list = new ArrayListListObject(); 求回答补充问题 list.get(position).add(Object);为什么会...
  3. django分页模块
  4. Node.js 教程
  5. java for新循环_Java 8 新语法习惯 (for 循环的函数替代方案)
  6. 理解Node.js的event loop
  7. 用SQL中的isnull函数注意了
  8. matlab 小波启发式阈值滤波,小波阈值去噪
  9. Asp.net MVC应用在IIS7上部署后403错误解决方案
  10. VSCode之调试html
  11. Android Studio控制台输出乱码,编译时期输出乱码,outpot乱码解决
  12. git提交时”warning: LF will be replaced by CRLF“提示
  13. PADS layout 显示叉X怎么回事?
  14. eclipse搭建javaweb开发环境
  15. c 打印二叉树_基础扩展 | 22. 遍历二叉树—前序遍历算法的VBA代码解析
  16. 联想G450 Linux wifi,联想g450无线网卡驱动,详细教您无线网卡安装教程
  17. 远程服务器网刻系统,网刻-wu123119-ChinaUnix博客
  18. Referrer 还是 Referer?
  19. 想说说关于在刷题网站(牛客 、C语言网、力扣)上测试样例过了但是OJ判错这档子事
  20. 【Java代码】MP3、flac歌曲批量生成同名的“xxx.lrc”歌词文件导入索尼黑砖二代

热门文章

  1. 软件体系架构课下作业01
  2. Docker第三方项目小结
  3. Android事件模型之interceptTouchEvnet ,onTouchEvent关系正解
  4. IOS - 单例模式+多线程
  5. dom4j解析XML文件,通过属性查找节点,出现异常
  6. 弹出框、遮罩层demo
  7. 用eclipse建立简单WebService客户端,使用WSDL,用于短信接口发送
  8. net core 通过js打印集合(创建树)
  9. Luogu4494 [HAOI2018]反色游戏 【割顶】
  10. 并发编程---死锁||递归锁---信号量---Event事件---定时器