python调用.DLL/.so方法详解——ctypes实用教程

python调用.DLL/.so方法详解——ctypes实用教程

常见问题

最多的问题就是各种找不到、打不开dll。有可能是目标路径问题,最简单的解决办法就是把dll和py脚本同级目录。另一种就是打开报错,dll可能存在依赖库,如果知道缺少什么库就拷贝过来或者添加环境变量,如果不知道就用dependency walker查一下。

基本使用方法

首先构造一个ctypes对象

import ctypes
def load_Library():
	dll=ctypes.CDLL("xxx.dll")

或者你也可以做成一个相对完整的接口

import ctypes,os,sys
def load_Library(path=''):
    global filepath
    if sys.platform == "win32":
        path = os.path.join(filepath, "xxx.dll")
        if not os.path.exists(path):
            print("xxx is not exist!")
            return
    elif sys.platform == "linux":
        path = os.path.join(filepath, "libxxx.so")
        if not os.path.exists(path):
            print("xxx is not exist!")
            return
    try:
        if sys.platform == "win32":
            return ctypes.CDLL(path)
        elif sys.platform == 'linux':
            return ctypes.cdll.LoadLibrary(path)
        else:
            print('Unknown or unsupported OS!')
    except Exception as e:
        print(e)

先调用一个最简单的 void(p*)()型函数:

def Close():
    try:
        load_Library().xxx_Close()
    except Exception as e:
        print(e)

带一个形参 void(p*)(uint):

def SysReset(devnum):
    try:
        load_Library().xxx_SysReset(ctypes.c_uint32(devnum))
    except Exception as e:
        print(e)

带一个指针 void(p*)(uint*):

def Initialize():
    dev = ctypes.c_uint32(0)
    try:
        load_Library().xxx_Initialize(ctypes.pointer(dev))
        return dev.value
    except Exception as e:
        print(e)

带字符串的函数 void(p*)(char*,uint,uint):

def SPIWriteFile(path, startBlock, stopBlock):
    file = ctypes.create_string_buffer(path.encode('gbk'), len(path))
    prog = ctypes.c_uint32(0)
    try:
        load_Library().xxx_SPIWriteFile(file, ctypes.c_uint32(startBlock), 
                                           ctypes.c_uint32(stopBlock),ctypes.pointer(prog))
    except Exception as e:
        print(e)

自定义数据类型

枚举,其实等价于int型,没有相对应的python类型:

(CmdFree, CmdStart, CmdPause, CmdStop) = (0, 1, 2, 3)

结构体,使用python类实现:

class PointTargetPara(ctypes.Structure):pass
PointTargetPara._fields_ = (('delay', ctypes.c_uint),
                               ('delayEnd', ctypes.c_uint),
                               ('speed', ctypes.c_int),
                               ('acc', ctypes.c_int),
                               ('ampI', ctypes.c_short),
                               ('ampQ', ctypes.c_short),
                               ('speedDopp', ctypes.c_int))

带自定义类型的函数 void(p*)(uint,PointTargetPara),以及调用方法:

def loadPointTargetPara(cardId, pointTargetPara):
    try:
        load_Library().loadPointTargetPara(ctypes.c_uint(cardId), pointTargetPara)
    except Exception as e:
        print(e)

par=PointTargetPara(delay=1,delayEnd=2)
loadPointTargetPara(0, par)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值