Python ctypes 模块操作dll动态库
最近折腾一下身份证读卡器,厂商只提供了Windows 32位的dll动态库文件,需要用python调用dll文件,读取身份证信息。
遇到的坑,32位的dll,只能用32位的python调用,64位的python会提示 OSError: [WinError 193] %1 不是有效的 Win32 应用程序。
Python ctypes模块简单示例
import ctypes
# 加载动态链接库
dll = ctypes.WinDLL("mydll.dll") # Windows平台下
dll = ctypes.CDLL("libmylib.so") # Linux平台下
# 调用C函数
result = mylib.my_function(1, 2)
print(result)
动态库导出函数
打开设备
long WINAPI iOpenPort(char* ErrMsg);
参数:ErrMsg:[OUT]返回错误信息,下同
返回值:非0表示失败
关闭设备
long WINAPI iClosePort();
返回值:非0表示失败
读取身份证/港澳台居住证信息
函数原型:
long WINAPI iReaderIDCard_CS(char* pPicFilePath, char* cardinfo, char* base64Data, char* ErrMsg);
功能:读取身份证信息
参数:pPicFilePath:[IN]照片路径,例:D:\\zp.jpg
Cardinfo:[OUT] 读卡成功时返回 "姓名|性别|民族|出生日期|地址|身份证号|发卡机关|发卡日期|卡有效期|通行证号码|签发次数|证件类型|"。
证件类型:I:外国人 J:港澳台居住证
base64Data[OUT] 身份证照片Base64编码,分配14100字节空间
返回值:非0表示失败
Python实现
import ctypes
# 加载SSCARD_SW.dll动态库
sscard = ctypes.cdll.LoadLibrary("./SSCARD_SW.dll")
# 定义iOpenPort函数的参数类型和返回值类型
sscard.iOpenPort.argtypes = [ctypes.c_char_p]
sscard.iOpenPort.restype = ctypes.c_long
# 调用iOpenPort函数
ErrMsg = ctypes.create_string_buffer(256) # 错误信息缓冲区
result = sscard.iOpenPort(ErrMsg)
if result != 0:
print("iOpenPort error:", ErrMsg.value.decode('gbk'))
# 定义iReaderIDCard_CS函数的参数类型和返回值类型
def iReaderIDCard_CS():
sscard.iReaderIDCard_CS.argtypes = [
ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p]
sscard.iReaderIDCard_CS.restype = ctypes.c_long
# 调用iReaderIDCard_CS函数
pPicFilePath = b"./idcard.jpg" # 身份证照片保存路径
cardinfo = ctypes.create_string_buffer(1024) # 身份证信息缓冲区
base64Data = ctypes.create_string_buffer(4096) # 身份证照片Base64编码数据缓冲区
result = sscard.iReaderIDCard_CS(
pPicFilePath, cardinfo, base64Data, ErrMsg)
if result != 0:
return result, ErrMsg.value.decode('gbk')
else:
sscard.iPosBeep()
return result, cardinfo.value.decode('gbk').split('|')
if __name__ == '__main__':
print(iReaderIDCard_CS())