最近研究了一下用Python调用dll,Python果然很神奇,代码不多既实现了从窗口创建到调用dll中函数的功能,程序也不复杂,最后打包成exe可直接执行的程序,测试过程中先用Python3.5,但用PyInstaller打包后的程序在xp系统上不能运行,后来用2.7,打包后的exe在xp或win7、win10上均可运行了,本人用的win10,程序安装如下:
1、https://www.python.org/-》download-》windows-》latest python 2 release-Python2.7.15
2、pip install pywin32
3、pip install PyInstaller
附源码如下:
#coding:utf-8
import tkinter
import Tkinter
import tkinter.messagebox
import tkinter as tk
from tkinter import ttk
from Tkinter import *
import ctypes
import sys #保证能正常把二代证输出的gb2312码能够转成utf-8
reload(sys)
sys.setdefaultencoding('gb2312')
dll= ctypes.windll.LoadLibrary('IdCard_GWI_V001.dll')
def openPort(port):
sBuf = 'A'
pStr = ctypes.c_char_p()
pStr.value = sBuf
iRet=dll.InitComm(int(port), pStr, 9600)
if iRet==0:
msgInfo.insert(INSERT,'打开端口成功\n')
msgInfo.insert(END,'')
else:
msgInfo.insert(INSERT,'打开端口失败\n')
msgInfo.insert(END,'')
def closePort():
iRet=dll.CloseComm()
msgInfo.insert(INSERT,'端口已经关闭\n')
msgInfo.insert(END,'')
def Authenticate():
iRet=dll.Authenticate()
if iRet==0:
msgInfo.insert(INSERT,'卡认证成功\n')
msgInfo.insert(END,'')
else:
msgInfo.insert(INSERT,'卡认证失败\n')
msgInfo.insert(END,'')
def ReadBaseMsg():
sDllPath='.\\'
pDllPath=ctypes.c_char_p()
pDllPath.value=sDllPath
sPhotoPath='.\\'
pPhotoPath=ctypes.c_char_p()
pPhotoPath.value=sPhotoPath
sMsg="\0"*1024
pMsg=ctypes.c_char_p()
pMsg.value=sMsg
intLen = ctypes.c_int(0)
#tkinter.messagebox.showinfo('二代证测试',sDllPath+sPhotoPath+sMsg)
iRet=dll.ReadBaseMsg(pDllPath,sPhotoPath,pMsg,ctypes.byref(intLen))
if iRet==0:
msgInfo.insert(INSERT,'读卡成功\n')
msg=ctypes.string_at(sMsg)
msg1 = msg.encode('utf-8')
msgInfo.insert(INSERT,msg1+'\n')
msgInfo.insert(END,'')
else:
msgInfo.insert(INSERT,'读卡失败\n')
msgInfo.insert(END,'')
def cardMessage(port):
iPortNo=int(port)
sBuf = 'A'
extendPort = ctypes.c_char_p()
extendPort.value = sBuf
iBaudRate=9600
iTimeOut=20
hotohead='c:\\temp\\head.bmp'
photohead = ctypes.c_char_p()
photohead.value = hotohead
sMsg="\0"*1024
buf=ctypes.c_char_p()
buf.value=sMsg
errInfo="\0"*1024
psErrInfo=ctypes.c_char_p()
psErrInfo.value=errInfo
iRet=dll.Get_Info(iPortNo,extendPort,iBaudRate, iTimeOut,photohead,buf, psErrInfo)
if iRet==0:
msgInfo.insert(INSERT,'读卡成功\n')
msg=ctypes.string_at(sMsg)
msg1 = msg.encode('utf-8')
msgInfo.insert(INSERT,msg1+'\n')
msgInfo.insert(END,'')
else:
msgInfo.insert(INSERT,'读卡失败\n')
msgInfo.insert(END,'')
def cardMessagePhoto(port):
iPortNo=int(port)
sBuf='A'
extendPort=ctypes.c_char_p()
extendPort.value=sBuf
iBaudRate=9600
iTimeOut=20
hotohead='C:\\TEMP\\head.jpg'
photohead=ctypes.c_char_p()
photohead.value=hotohead
hotoface='C:\\TEMP\\face.jpg'
photoface=ctypes.c_char_p()
photoface.value=hotoface
hotoback='C:\\TEMP\\back.jpg'
photoback=ctypes.c_char_p()
photoback.value=hotoback
sMsg="\0"*1024
buf=ctypes.c_char_p()
buf.value=sMsg
errInfo="\0"*1024
psErrInfo=ctypes.c_char_p()
psErrInfo.value=errInfo
iRet=dll.Get_Info_WithPhoto(iPortNo,extendPort ,iBaudRate,iTimeOut,photohead,photoface,photoback,buf,psErrInfo)
if iRet==0:
msgInfo.insert(INSERT,'读卡成功\n')
msg=ctypes.string_at(sMsg)
msg1 = msg.encode('utf-8')
msgInfo.insert(INSERT,msg1+'\n')
msgInfo.insert(END,'')
else:
msgInfo.insert(INSERT,'读卡失败\n')
msgInfo.insert(END,'')
def cleanText():
msgInfo.delete(1.0,END)
#tkinter.messagebox.showinfo('二代证测试',str(port))
root=Tk()
root.title('二代证测试程序')
root['bg'] = '#bcbcbc'
root.attributes("-alpha", 0.9)
root.geometry('800x500')
#dhl:显示交互信息的文本框
msgInfo = Text(root,width=110,height=30)
msgInfo.place(x=10,y=90,anchor=NW)
#dhl:输入端口号
Label(root,text='端口号').place(x=10,y=10,anchor=NW)
port = tk.StringVar()
port.set(9)
portNum = ttk.Entry(root, width=6,textvariable=port)
portNum.place(x=55,y=10,anchor=NW)
#dhl:打开端口按钮
oPort=Button(root,text='打开端口',width=10,command=lambda:openPort(port.get()))
oPort.place(x=10,y=40,anchor=NW)
#dhl:卡认证
Aut=Button(root,text='认证卡片',width=10,command=lambda:Authenticate())
Aut.place(x=100,y=40,anchor=NW)
#dhl:读信息
Read=Button(root,text='读卡',width=10,command=lambda:ReadBaseMsg())
Read.place(x=190,y=40,anchor=NW)
#dhl:关闭端口按钮
cPort=Button(root,text='关闭端口',width=10,command=lambda:closePort())
cPort.place(x=280,y=40,anchor=NW)
#Label(root,text='XX农信接口',height=2).place(x=450,y=40,anchor=NW)
Label(root,bitmap='info',text=' XX农信-->>', height=22,compound=Tkinter.LEFT).place(x=410,y=40,anchor=NW)
#dhl:XX农信的接口1,获取文字信息
cardMsg=Button(root,text='读卡信息',width=10,command=lambda:cardMessage(port.get()))
cardMsg.place(x=530,y=40,anchor=NW)
#dhl:XX农信的接口1,获取文字及图片
cardMsgPhoto=Button(root,text='文字图片',width=10,command=lambda:cardMessagePhoto(port.get()))
cardMsgPhoto.place(x=615,y=40,anchor=NW)
#dhl:清除显示内容
clean=Button(root,text='清除',width=10,command=lambda:cleanText())
clean.place(x=700,y=40,anchor=NW)
root.mainloop()