Python ctypes 模块操作dll动态库
in Python with 0 comment

最近折腾一下身份证读卡器,厂商只提供了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())
Responses