QT读取身份证信息
使用的是华视的读卡器,先去官网(http://www.chinaidcard.com/)下载读卡二次开发SDK,里边有二次开发的说明文档和示例,复制termb.dll 、sdtapi.dll、WltRs.dll等到程序路径下。使用 QLibrary 从 termb.dll 加载身份证读取相关的函数。
代码:
.h
#ifndef BP_READCARD_H
#define BP_READCARD_H
#include <QObject>
#include <QLibrary>
#include <QDebug>
typedef int __stdcall (*CVR_InitComm)(int); //初始化
typedef int __stdcall (*CVR_Authenticate)(); //卡认证
typedef int __stdcall (*CVR_Read_FPContent)(); //读卡
typedef int __stdcall (*CVR_GetPeopleName)(char *,int &); //获取姓名
typedef int __stdcall (*CVR_GetPeopleIDCode)(char *,int &); //获取身份证号
typedef int __stdcall (*CVR_CloseComm)(); //关闭链接
//身份证信息
struct stu_card_info
{
QString name;
QString ID;
};
class ReadCard:public QObject
{
Q_OBJECT
public:
ReadCard();
~ReadCard();
bool init_cvr();
private:
bool read_card_info();
bool load_function();
signals:
void read_finished(stu_card_info info);
void read_error();
private slots:
void read_card();
private:
//身份证读取函数指针
CVR_InitComm func_cvr_InitComm {nullptr};
CVR_Authenticate func_cvr_Authenticate {nullptr};
CVR_Read_FPContent func_cvr_Read_FPContent {nullptr};
CVR_GetPeopleName func_cvr_GetPeopleName {nullptr};
CVR_GetPeopleIDCode func_cvr_GetPeopleIDCode{nullptr};
CVR_CloseComm func_cvr_CloseComm {nullptr};
//读取身份证的缓冲区
char m_buf[40];
int m_buf_size = 40;
stu_card_info m_info;
};
#endif // BP_READCARD_H
.cpp
#include "bp_readcard.h"
#include <QFile>
ReadCard::ReadCard()
{
}
ReadCard::~ReadCard()
{
if(func_cvr_CloseComm)
func_cvr_CloseComm();
}
//加载dll中的函数指针
bool ReadCard::load_function()
{
func_cvr_InitComm = {nullptr};
func_cvr_Authenticate = {nullptr};
func_cvr_Read_FPContent = {nullptr};
func_cvr_GetPeopleName = {nullptr};
func_cvr_GetPeopleIDCode= {nullptr};
func_cvr_CloseComm = {nullptr};
qRegisterMetaType<stu_card_info>("stu_card_info");
QLibrary lib("termb.dll");
if(lib.load()) //加载身份证读取库中的函数
{
func_cvr_InitComm = (CVR_InitComm)lib.resolve("CVR_InitComm");
if(!func_cvr_InitComm)
qDebug()<<"CVR_InitComm 解析失败"<<lib.errorString();
func_cvr_GetPeopleName = (CVR_GetPeopleName)lib.resolve("GetPeopleName");
if(!func_cvr_GetPeopleName)
qDebug()<<"CVR_GetPeopleName 解析失败"<<lib.errorString();
func_cvr_GetPeopleIDCode = (CVR_GetPeopleIDCode)lib.resolve("GetPeopleIDCode");
if(!func_cvr_GetPeopleIDCode)
qDebug()<<"CVR_GetPeopleIDCode 解析失败"<<lib.errorString();
func_cvr_Authenticate = (CVR_Authenticate)lib.resolve("CVR_Authenticate");
if(!func_cvr_Authenticate)
qDebug()<<"CVR_Authenticate 解析失败"<<lib.errorString();
func_cvr_Read_FPContent = (CVR_Read_FPContent)lib.resolve("CVR_Read_FPContent");
if(!func_cvr_Read_FPContent)
qDebug()<<"CVR_Read_FPContent 解析失败"<<lib.errorString();
func_cvr_CloseComm = (CVR_CloseComm)lib.resolve("CVR_CloseComm");
if(!func_cvr_CloseComm)
qDebug()<<"CVR_CloseComm 解析失败"<<lib.errorString();
}
else
qDebug()<<"termb.dll load faild."<<lib.errorString();
return (func_cvr_InitComm && func_cvr_Authenticate && func_cvr_Read_FPContent && func_cvr_GetPeopleName && func_cvr_GetPeopleIDCode && func_cvr_CloseComm);
}
//初始化
bool ReadCard::init_cvr()
{
if(!load_function()) //加载函数失败
return false;
int iPort, iRetUSB = 0, iRetCOM = 0;
for (iPort = 1001; iPort <= 1004; iPort++) //USB
{
iRetUSB = func_cvr_InitComm(iPort);
if (iRetUSB == 1)
break;
}
if (iRetUSB != 1)
{
for (iPort = 1; iPort <= 4; iPort++) //port
{
iRetCOM = func_cvr_InitComm(iPort);
if (iRetCOM == 1)
break;
}
}
if ((iRetCOM == 1) || (iRetUSB == 1))
return true;
return false;
}
//读卡姓名身份证号
bool ReadCard::read_card_info()
{
if(func_cvr_Read_FPContent() == 1)
{
memset(m_buf,0,m_buf_size);
if(1 == func_cvr_GetPeopleName(m_buf,m_buf_size))
{
m_info.name = QString::fromLocal8Bit(m_buf);
memset(m_buf,0,m_buf_size);
if(1 == func_cvr_GetPeopleIDCode(m_buf,m_buf_size))
{
m_info.ID = m_buf;
emit read_finished(m_info);
//删除读取身份证生成的文件
QFile::remove("wz.txt");
QFile::remove("fp.dat");
QFile::remove("zp.bmp");
return true;
}
}
}
emit read_error();
return false;
}
//读卡,尝试读,读失败尝试认证,认证成功再读一次
void ReadCard::read_card()
{
if(!read_card_info())
{
if(1 == func_cvr_Authenticate())
{
read_card_info();
}
}
}
使用时,调用 init_cvr 初始化成功后调用 read_card 读取身份证信息,然后接收读取完成的信号即可。读卡耗时比较久大概会有几百毫秒。