如何使用Python调用dll动态链接库?

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_39198406/article/details/84889047

1. 需求

最近有这样一个需求:网络上下载了大佬的深度学习图像识别模型,想要集成到自己的后端作为服务调用。
模型是.dll文件,而我这边使用的是Python。

2. 思路

.dll是使用C或者C++编译的动态链接库,一般留有函数入口可以进行调用。
首先我们通过阅读原项目的源码,找到入口的函数名称、传参规则和类型、返回值类型。
然后使用Python ctype库加载dll库,并且调用函数,得到返回值。

3. 读原项目源码

我们发现原项目中可以这样调用

recognize(content=>bytes, len(content)=>int)
return "1234"=>str

这意味着,我们在python中调用的时候可以把recognize这个函数作为入口。

4. ctype

网络上ctype的资料很多,这里不多说,直接上代码和注释。

from ctypes import *

dll = windll.LoadLibrary("ocr.dll")  # 加载链接库
ocr = dll.ocr  # 把function赋值
ocr.argtypes = [c_char_p, c_int]  # 指定传入参数的类型,这里的c_char_p和c_int分别代表二进制类型和整型
ocr.restype = c_char_p  # 指定返回值类型(这里有个坑,如果返回得不到你想要的结果,可以分别尝试c_char_p和c_wchar_p)
with open("./test.jpg", "rb") as f:
    content = f.read()
# 这里打开一张图片来构造一个二进制数据
r = dll.ocr(content, len(content))  # 按照指定类型传入数据
print(r)  # 得到返回值
print(r.decode("utf-8"))

这里注意:如果ocr这个函数返回二进制类型但是选择字符串类型作为返回值,程序会自动帮你解码,但是解码结果存在问题。所以这里最好把返回值类型指定为二进制!

5. 过程中遇到的错误

5.1 OSError: [WinError 193] %1 不是有效的 Win32 应用程序

说明dll文件只支持32位调用,你可以安装一个32位的python使用。

5.2 Procedure called with not enough arguments (4 bytes missing) or wrong calling convention error occuring when trying to call a function of a ctype DLL

  1. dll = cdll.LoadLibrary(“ocr.dll”)
  2. dll = windll.LoadLibrary(“ocr.dll”)
    如果报错可以试一下另外一种加载方式

参考:https://stackoverflow.com/questions/26201751/procedure-called-with-not-enough-arguments-4-bytes-missing-or-wrong-calling-co

dll反编译:https://www.jb51.net/softs/629352.html
官方文档:https://docs.python.org/3.5/library/ctypes.html#
参考1:https://blog.csdn.net/awakeljw/article/details/79369703
参考2:https://www.cnblogs.com/night-ride-depart/p/4907613.html

猜你喜欢

转载自blog.csdn.net/weixin_39198406/article/details/84889047