常见问题
最多的问题就是各种找不到、打不开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)