ctypes python 结构体_Python 中 ctypes 的使用

本文详细介绍了如何在Python中使用ctypes库调用C标准库,如在Windows和Linux下加载动态链接库。通过实例展示了如何定义结构体、调用C函数,并处理字符串类型错误。还提到了将Python函数注册为C的回调函数的方法。
摘要由CSDN通过智能技术生成

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]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值