intro ctypes是python的一个函数库,提供和C语言兼容的数据类型,可以直接调用动态链接库中的导出函数。 为了使用ctypes,必须依次完成以下步骤:
加载动态链接库
将python对象转换成ctypes所能识别的参数
使用ctypes所能识别的参数调用动态链接库中的函数
仅支持简单使用,详情请参考官方文档python doc
基础类型
ctypes 类型
C 类型
Python 类型
c_bool
_Bool
bool (1)
c_char
char
单字符字节对象
c_wchar
wchar_t
单字符字符串
c_byte
char
整型
c_ubyte
unsigned char
整型
c_short
short
整型
c_ushort
unsigned short
整型
c_int
int
整型
c_uint
unsigned int
整型
c_long
long
整型
c_ulong
unsigned long
整型
c_longlong
__int64 或 long long
整型
c_ulonglong
unsigned __int64 或 unsigned long long
整型
c_size_t
size_t
整型
c_ssize_t
ssize_t 或 Py_ssize_t
整型
c_float
float
浮点数
c_double
double
浮点数
c_longdouble
long double
浮点数
c_char_p
char * (以 NUL 结尾)
字节串对象或 None
c_wchar_p
wchar_t * (以 NUL 结尾)
字符串或 None
c_void_p
void *
int 或 None
usage cdll demo:
import sys, ctypesfrom platform import system, architecturewindows = 'windows' in system.lower() if windows: api = ctypes.WinDLL('lib.dll' ) else : api = ctypes.CDLL('lib.so' ) long_effect = sizeof(c_long) != sizeof(c_int) if not long_effect: c_long = c_longlong c_ulong = c_ulonglong
simple:
from ctypes import *demo_api = CDLL("lib.so" ) demo_api.add.argtypes = [c_int, c_int] demo_api.add.restype = c_int res = demo_api.add(c_int(5 ), c_int(6 )) print (res)
pointer demo:
from ctypes import *demo_api = CDLL("lib.so" ) demo_api.create_handle.argtypes = [POINTER(c_void_p)] demo_api.create_handle.restype = c_int req = c_void_p() res = demo_api.create_handle(byref(req)) demo_api.free_handle.argtypes = [c_void_p, c_int] demo_api.free_handle.restype = c_int res = demo_api.free_handle(req, 9 )
struct demo:
from ctypes import *demo_api = CDLL("lib.so" ) class REQ (Structure ): _pack_ = True _fields_ = [ ("c" , c_char), ("list" , c_int * 256 ), ("i" , c_uint), ] demo_api.request.argtypes = [REQ] demo_api.request.restype = c_int req = REQ('1' , [2 ,3 ,4 ], 3 ) res = demo_api.request(req)
callback demo:
from ctypes import *demo_api = CDLL("lib.so" ) class REQ (Structure ): _fields_ = [ ("c" , c_char), ("list" , c_int * 256 ), ("i" , c_uint), ] if windows: callback_type = ctypes.WINFUNCTYPE(c_int, REQ) else : callback_type = ctypes.CFUNCTYPE(c_int, REQ) def print_log (i, data ): print (i, data) print (data.c) print (data.__dict__) demo_api.func.argtypes = [c_void_p] demo_api.func.restype = c_int callback_func = callback_type(print_log) res = demo_api.func(callback_func)