第二十二篇 ctypes模块,如何用python调用so文件

心得:最近觉得自己生活有些空,身边的朋友越来越少了,越来越渴望自己变得更加强,靠得住,完全不满足于现在的自己。所谓孤独中成长嘛,最后留下来的将是强者。

ctypes模块
它是做什么的,是可以用python调用c语言动态库的一种模块,相当于python和c的接口,有效的连接起了两种语言。

Loading dynamic link libraries
加载动态链接库

windos:

import ctypes
dll = ctypes.windll.LoadLibrary( 'test.dll' )

lunix:

from ctypes import *
cur=cdll.LoadLibrary("libc.so") 
cur.c_func()

2.基本数据类型:
第二十二篇 ctypes模块,如何用python调用so文件_第1张图片
定义参数类型:
1.单字符定义

>>> import ctypes
>>> i=ctypes.c_int(42)  #定义整型
>>>> i.value      #读取参数值
42

2.结构体定义:

结构和联合必须从导出Structure和Union其中所定义的基类ctypes模块。每个子类都必须定义一个_fields_属性。_fields_必须是包含字段名称和字段类型的2元组列表。

>>> from ctypes import *
>>> class POINT(Structure):
...     _fields_ = [("x", c_int),
...                 ("y", c_int)]
	res=POINT()
	cur.c_func(ctypes.brefy(res))  #将结构体传入c函数

联合体定义
类似于结构体的定义,继承的类为Union

class U_test(ctypes.Union):

3.数组的定义
数组是序列,包含固定数量的相同类型的实例。

推荐的创建数组类型的方法是将数据类型乘以正整数
TenPointsArrayType = POINT * 10

>>> from ctypes import *
>>> TenIntegers = c_int * 10
>>> ii = TenIntegers(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) #当括号为空时,用0填充
>>> print ii
<c_long_Array_10 object at 0x...>
>>> for i in ii: print i,
...
1 2 3 4 5 6 7 8 9 10
>>>

4.指针:
通过调用pointer()一个ctypes类型的函数来创建指针实例,c语言通常用指针来传递参数,通过地址的传递能更快的数据进行交互。

>>> import ctypes
>>> i=ctypes.c_int(42)
>>> i_p=ctypes.pointer(i)
>>> i_p
<__main__.LP_c_long object at 0x0000019D25BD24C0>
>>> i_p.contents      #指针右contents的用法
c_long(42)
>>> i
c_long(42)
>>> i.value    #有一个value用法
42

5.指针传递

>>> i = c_int()
>>> f = c_float()
>>> s = create_string_buffer('\000' * 32)
>>> print i.value, f.value, repr(s.value)
0 0.0 ''
>>> libc.sscanf("1 3.14 Hello", "%d %f %s",
...             byref(i), byref(f), s)
3
>>> print i.value, f.value, repr(s.value)
1 3.1400001049 'Hello'
>>>

有时C API函数需要一个指向数据类型的指针作为参数,可能写入相应的位置,或者数据太大而无法通过值传递。这也被称为通过引用传递参数。
ctypesbyref()通过引用导出用于传递参数的函数。这个pointer()函数可以达到同样的效果,但是pointer()由于它构造了一个真正的指针对象,因此做了很多工作,所以byref()如果你不需要Python本身的指针对象,使用它会更快。

你可能感兴趣的:(python)