说明

ctypes.cdll.LoadLibrary加载dll
eval函数用来执行一个字符串表达式,并返回表达式的值。
exec执行储存在字符串或文件中的Python语句,相比于 eval,exec可以执行更复杂的 Python 代码。
*args可以展开数组类型的参数。
**kwargs可以展开字典类型的参数。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import ctypes
from ctypes import *
import json

def loadtext(path):
try:
f = open(path,"r")
txt = f.read()
f.close()
return txt
except Exception as e:
print("load file error! {}".format(path))
return None
return None


# to json
def txt2json(text):
try:
jsondict=json.loads(text)
return jsondict
except Exception as e:
print('json error!')
return None
return None


# to txt
def json2txt(jsondict):
try:
text=json.dumps(jsondict)
return text
except Exception as e:
print('json error!')
return None
return None


# 只支持基础类型
def call_func(obj, name, params, types, restype=None):
try:
funcname="obj."+name
strtypes=""
args=[]
for i in range(len(params)):
args.append(params[i])
if strtypes=="":
strtypes=types[i]
else:
strtypes=strtypes+","+types[i]
if "" != strtypes:
strtypes="["+strtypes+"]"
sss = funcname+".argtypes="+strtypes
# 设置参数类型
exec(sss)
if restype:
sss = funcname+".restype="+restype
# 设置返回类型
exec(sss)
# 调用函数
res = eval(funcname)(*args)
print("{} {} {} ".format(funcname, params, res))
except BaseException as e:
return False, str(e)
return True , res

def call_dll_funcs(data):
path = data["path"]
dll = data["dll"]
calls=data["calls"]
msg={"dll":dll}
if not dll or not path:
msg["msg"] = "dll or path不能为空!"
return False , msg
if "" == dll or "" == path:
msg["msg"] = "dll or path不能为空!"
return False , msg
msg ={}
try:
obj = ctypes.cdll.LoadLibrary(path)
for name in calls:
params = calls[name].get("params")
types = calls[name].get("types")
restype = calls[name].get("restype")
if not params or not types:
msg["msg"] = "params or types不能为空!"
return False , msg
if len(params) != len(types):
msg["msg"] = "params and types数量不等!"
return False , msg
flg, res = call_func(obj, name, params, types, restype)
msg[name]={}
if flg:
msg[name]["res"] = res
else:
msg[name]["msg"] = res
except BaseException as e:
msg["msg"]=str(e)
return False , msg
return True, msg


def test_loaddll2(mjs):
if not mjs:
return False, "空参数"
print("call={}", mjs)
msgs = {}
for index in mjs:
data = mjs[index]
res, msg = call_dll_funcs(data)
msgs[index]=msg
print(msgs)
js = json2txt(msgs)
print("msg={}".format(js))
return True, msgs

if __name__ == "__main__":
js = '{"d1":{"dll":"dynamic.dll","path":"./dynamic.dll","calls":{"addf":{"params":[1.1,2.2],"types":["c_float","c_float"],"restype":"c_float"},"add":{"params":[1,2],"types":["c_int","c_int"],"restype":"c_int"},"sub":{"params":[1,2],"types":["c_int","c_int"]},"add3":{"params":[1,2,3],"types":["c_int","c_int","c_int"]} } } }'

mapa = txt2json(js)
test_loaddll2(mapa)

输出

在这里插入图片描述

测试用DLL

在这里插入图片描述

参考

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