Python 中 ctypes 的使用

  1. 简介
  2. ctypes 数据类型
  3. 定义结构体,调用 C 函数
  4. 调用 C 函数接口的字符串类型错误
  5. 注册成 C 的回调函数
  6. 参考

简介

文档:https://docs.python.org/3/library/ctypes.html

Python 的 ctypes 要使用 C 函数,需要先将 C 编译成动态链接库的形式,即 Windows 下的 .dll 文件,或者 Linux 下的 .so 文件。先来看一下 ctypes 怎么使用 C 标准库。

Windows 系统下的 C 标准库动态链接文件为 msvcrt.dll (一般在目录 C:\Windows\System32 和 C:\Windows\SysWOW64 下分别对应 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 数据类型

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 函数接口的字符串类型错误

https://blog.csdn.net/yuanlulu/article/details/79877305

python2 的源码直接在 python3.5 运行(出错):

net = dn.load_net("cfg/yolov3.cfg", "weights/yolov3.weights", 0)

ctypes.ArgumentError: argument 1: <class 'TypeError'>: 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 的回调函数

见:Python 调用海康 SDK

参考

https://www.cnblogs.com/gaowengang/p/7919219.html


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 bin07280@qq.com

文章标题:Python 中 ctypes 的使用

文章字数:607

本文作者:Bin

发布时间:2018-09-28, 16:06:22

最后更新:2019-08-06, 00:07:35

原始链接:http://coolview.github.io/2018/09/28/Python/Python%20%E4%B8%AD%20ctypes%20%E7%9A%84%E4%BD%BF%E7%94%A8/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录