Python 的 ctypes 要使用 C 函数,需要先将 C 编译成动态链接库的形式,即 Windows 下的 .dll 文件,或者 Linux 下的 .so 文件。先来看一下 ctypes 怎么使用 C 标准库。
Windows 系统下的 C 标准库动态链接文件为 msvcrt.dll (一般在目录 C:WindowsSystem32 和 C:WindowsSysWOW64 下分别对应 32-bit 和 64-bit,使用时不用刻意区分,Python 会选择合适的)
Linux 系统下的 C 标准库动态链接文件为 libc.so.6 (以 64-bit Ubuntu 系统为例, 在目录 /lib/x86_64-linux-gnu 下)
例如,以下代码片段导入 C 标准库,并使用 printf 函数打印一条消息,
import platform
from ctypes import *
# 导入 dll 文件的多种方式
if platform.system() == 'Windows':
libc = cdll.LoadLibrary('msvcrt.dll')
#libc = windll.LoadLibrary('msvcrt.dll') # Windows only
#libc = oledll.LoadLibrary('msvcrt.dll') # Windows only
#libc = pydll.LoadLibrary('msvcrt.dll')
#libc = CDLL('msvcrt.dll')
#libc = WinDLL('msvcrt.dll') # Windows only
#libc = OleDLL('msvcrt.dll') # Windows only
#libc = PyDLL('msvcrt.dll')
elif platform.system() =='Linux':
libc = cdll.LoadLibrary('libc.so.6')
#libc = pydll.LoadLibrary('libc.so.6')
#libc = CDLL('libc.so.6')
#libc = PyDLL('libc.so.6')
libc.printf('Hello ctypes!n')
ctypes 数据类型
定义结构体,调用 C 函数class POINT_struct(Structure):
_fields_ = [('x', c_long), ('y', c_long), ('info', c_char*512), ('Data', c_ubyte*2560)]
这里使用 c_ubyte 类型,是因为使用 c_char 类似,将该结构体中的值赋给另一个结构体时,碰见 0 会停止,导致数据不完整。赋值时可以使用 memmove(pStruct.Data, pData, 2560)。
function = dll.function # 要调用 C 的函数
function.restype = c_int # C 函数的返回值
function.argtypes = (c_short, c_char_p, c_uint, c_int, c_void_p, c_void_p, c_void_p) # C 函数参数
p_struct = POINT_struct()
p_struct.x = c_long(0)
p_struct.y = c_long(0)
res = function(byref(p_struct)) # 调用 C 的函数
调用 C 函数接口的字符串类型错误
python2 的源码直接在 python3.5 运行(出错):
net = dn.load_net("cfg/yolov3.cfg", "weights/yolov3.weights", 0)
ctypes.ArgumentError: argument 1: : wrong type
使用类型转换(出错):
net = dn.load_net(c_char_p("cfg/yolo.cfg"), c_char_p("weights/yolov3.weights"), c_int(0))
TypeError: bytes or integer address expected instead of str instance
utf8 转换(OK 了):
net = dn.load_net("cfg/yolov3.cfg".encode("utf-8"), "weights/yolov3.weights".encode("utf-8"), 0)
注册成 C 的回调函数
参考转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 [email protected]