之前为了能做硬件操作学习了C++,一直停留在试验阶段。由于之前项目都是HIS做好读卡对接了,就直接C#调HIS的dll了,一直没实际用C++对接过读卡器。这次终于有了个读卡机会,还有厂商配合,哈哈。

采用C++包装读卡操作为一个读卡方法如下:

//检验读身份证包装
#include <iostream>
#include "windows.h"
using namespace std;//读身份证对外函数
extern "C" __declspec(dllexport) const char* LISReadIDCard();//方法定义
typedef int(__stdcall* _UCommand1)(unsigned char* pCmd, int* parg0, int* parg1, int* parg2);
typedef int(__stdcall* _GetAddr)(char* pbuf);
typedef int(__stdcall* _GetBegin)(char* pbuf);
typedef int(__stdcall* _GetName)(char* pbuf);
typedef int(__stdcall* _GetSex)(char* pbuf);
typedef int(__stdcall* _GetSexGB)(char* pbuf);
typedef int(__stdcall* _GetFolk)(char* pbuf);
typedef int(__stdcall* _GetFolkGB)(char* pbuf);
typedef int(__stdcall* _GetIDNum)(char* pbuf);
typedef int(__stdcall* _GetDep)(char* pbuf);
typedef int(__stdcall* _GetBirth)(char* pbuf);
typedef int(__stdcall* _GetEnd)(char* pbuf);
typedef int(__stdcall* _GetNewAddr)(char* pbuf);
typedef int(__stdcall* _FID_GetEnName)(char* pbuf);
typedef int(__stdcall* _FID_GetSex)(char* pbuf);
typedef int(__stdcall* _FID_GetSexGB)(char* pbuf);
typedef int(__stdcall* _FID_GetIDNum)(char* pbuf);
typedef int(__stdcall* _FID_GetNationality)(char* pbuf);
typedef int(__stdcall* _FID_GetChNationality)(char* pbuf);
typedef int(__stdcall* _FID_GetChName)(char* pbuf);
typedef int(__stdcall* _FID_GetBegin)(char* pbuf);
typedef int(__stdcall* _FID_GetEnd)(char* pbuf);
typedef int(__stdcall* _FID_GetBirth)(char* pbuf);
typedef int(__stdcall* _FID_GetVersion)(char* pbuf);
typedef int(__stdcall* _FID_GetDep)(char* pbuf);
typedef int(__stdcall* _GetSAMIDToStr)(char* id);
typedef int(__stdcall* _GID_GetName)(char* pbuf);
typedef int(__stdcall* _GID_GetSex)(char* pbuf);
typedef int(__stdcall* _GID_GetSexGB)(char* pbuf);
typedef int(__stdcall* _GID_GetBirth)(char* pbuf);
typedef int(__stdcall* _GID_GetAddr)(char* pbuf);
typedef int(__stdcall* _GID_GetIDNum)(char* pbuf);
typedef int(__stdcall* _GID_GetDep)(char* pbuf);
typedef int(__stdcall* _GID_GetBegin)(char* pbuf);
typedef int(__stdcall* _GID_GetEnd)(char* pbuf);
typedef int(__stdcall* _GID_GetPassPortId)(char* pbuf);
typedef int(__stdcall* _GID_SignCount)(char* pbuf);
typedef int(__stdcall* _GID_GetCardType)(char* pbuf);
_UCommand1              UCommand1;
_GetAddr                GetAddr;
_GetBegin               GetBegin;
_GetName                GetName;
_GetSex                 GetSex;
_GetSexGB               GetSexGB;
_GetFolk                GetFolk;
_GetFolkGB              GetFolkGB;
_GetIDNum               GetIDNum;
_GetDep                 GetDep;
_GetBirth               GetBirth;
_GetEnd                 GetEnd;
_GetNewAddr             GetNewAddr;
_FID_GetEnName          FID_GetEnName;
_FID_GetSex             FID_GetSex;
_FID_GetSexGB           FID_GetSexGB;
_FID_GetIDNum           FID_GetIDNum;
_FID_GetNationality     FID_GetNationality;
_FID_GetChNationality   FID_GetChNationality;
_FID_GetChName          FID_GetChName;
_FID_GetBegin           FID_GetBegin;
_FID_GetEnd             FID_GetEnd;
_FID_GetBirth           FID_GetBirth;
_FID_GetVersion         FID_GetVersion;
_FID_GetDep             FID_GetDep;
_GetSAMIDToStr          GetSAMIDToStr;
_GID_GetName            GID_GetName;
_GID_GetSex             GID_GetSex;
_GID_GetSexGB           GID_GetSexGB;
_GID_GetBirth           GID_GetBirth;
_GID_GetAddr            GID_GetAddr;
_GID_GetIDNum           GID_GetIDNum;
_GID_GetDep             GID_GetDep;
_GID_GetBegin           GID_GetBegin;
_GID_GetEnd             GID_GetEnd;
_GID_GetPassPortId      GID_GetPassPortId;
_GID_SignCount          GID_SignCount;
_GID_GetCardType        GID_GetCardType;/// <summary>
/// 字符串转宽字符串
/// </summary>
/// <param name="orig"></param>
/// <returns></returns>
LPCWSTR StringToLPCWSTR(std::string orig)
{size_t origsize = orig.length() + 1;const size_t newsize = 100;size_t convertedChars = 0;wchar_t* wcstring = (wchar_t*)malloc(sizeof(wchar_t) * (orig.length() - 1));mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);return wcstring;
}/// <summary>
/// 初始化读卡
/// </summary>
/// <returns>返回空就成功,返回-1^失败原因</returns>
const char* InitFunc()
{HINSTANCE hDll = LoadLibraryEx(StringToLPCWSTR("RdCard.dll"), 0, LOAD_WITH_ALTERED_SEARCH_PATH);if (hDll == NULL){return "-1^RdCard.dll加载失败";}UCommand1 = (_UCommand1)GetProcAddress(hDll, "UCommand1");GetAddr = (_GetAddr)GetProcAddress(hDll, "GetAddr");GetBegin = (_GetBegin)GetProcAddress(hDll, "GetBegin");GetName = (_GetName)GetProcAddress(hDll, "GetName");GetSex = (_GetSex)GetProcAddress(hDll, "GetSex");GetSexGB = (_GetSexGB)GetProcAddress(hDll, "GetSexGB");GetFolk = (_GetFolk)GetProcAddress(hDll, "GetFolk");GetFolkGB = (_GetFolkGB)GetProcAddress(hDll, "GetFolkGB");GetIDNum = (_GetIDNum)GetProcAddress(hDll, "GetIDNum");GetDep = (_GetDep)GetProcAddress(hDll, "GetDep");GetBirth = (_GetBirth)GetProcAddress(hDll, "GetBirth");GetEnd = (_GetEnd)GetProcAddress(hDll, "GetEnd");GetNewAddr = (_GetNewAddr)GetProcAddress(hDll, "GetNewAddr");FID_GetEnName = (_FID_GetEnName)GetProcAddress(hDll, "FID_GetEnName");FID_GetSex = (_FID_GetSex)GetProcAddress(hDll, "FID_GetSex");FID_GetSexGB = (_FID_GetSexGB)GetProcAddress(hDll, "FID_GetSexGB");FID_GetIDNum = (_FID_GetIDNum)GetProcAddress(hDll, "FID_GetIDNum");FID_GetNationality = (_FID_GetNationality)GetProcAddress(hDll, "FID_GetNationality");FID_GetChNationality = (_FID_GetChNationality)GetProcAddress(hDll, "FID_GetChNationality");FID_GetChName = (_FID_GetChName)GetProcAddress(hDll, "FID_GetChName");FID_GetBegin = (_FID_GetBegin)GetProcAddress(hDll, "FID_GetBegin");FID_GetEnd = (_FID_GetEnd)GetProcAddress(hDll, "FID_GetEnd");FID_GetBirth = (_FID_GetBirth)GetProcAddress(hDll, "FID_GetBirth");FID_GetVersion = (_FID_GetVersion)GetProcAddress(hDll, "FID_GetVersion");FID_GetDep = (_FID_GetDep)GetProcAddress(hDll, "FID_GetDep");GID_GetName = (_GID_GetName)GetProcAddress(hDll, "GID_GetName");GID_GetSex = (_GID_GetSex)GetProcAddress(hDll, "GID_GetSex");GID_GetSexGB = (_GID_GetSexGB)GetProcAddress(hDll, "GID_GetSexGB");GID_GetBirth = (_GID_GetBirth)GetProcAddress(hDll, "GID_GetBirth");GID_GetAddr = (_GID_GetAddr)GetProcAddress(hDll, "GID_GetAddr");GID_GetIDNum = (_GID_GetIDNum)GetProcAddress(hDll, "GID_GetIDNum");GID_GetDep = (_GID_GetDep)GetProcAddress(hDll, "GID_GetDep");GID_GetBegin = (_GID_GetBegin)GetProcAddress(hDll, "GID_GetBegin");GID_GetEnd = (_GID_GetEnd)GetProcAddress(hDll, "GID_GetEnd");GID_GetPassPortId = (_GID_GetPassPortId)GetProcAddress(hDll, "GID_GetPassPortId");GID_SignCount = (_GID_SignCount)GetProcAddress(hDll, "GID_SignCount");GID_GetCardType = (_GID_GetCardType)GetProcAddress(hDll, "GID_GetCardType");GetSAMIDToStr = (_GetSAMIDToStr)GetProcAddress(hDll, "GetSAMIDToStr");if (UCommand1 == NULL || GetAddr == NULL || GetBegin == NULL || GetName == NULL || GetSex == NULL || GetSexGB == NULL || GetFolk == NULL || GetFolkGB == NULL || GetIDNum == NULL || GetDep == NULL || GetBirth == NULL || GetEnd == NULL || GetNewAddr == NULL || FID_GetEnName == NULL || FID_GetSex == NULL || FID_GetSexGB == NULL || FID_GetIDNum == NULL || FID_GetNationality == NULL || FID_GetChNationality == NULL || FID_GetChName == NULL || FID_GetBegin == NULL || FID_GetEnd == NULL || FID_GetBirth == NULL || FID_GetVersion == NULL || FID_GetDep == NULL || GetSAMIDToStr == NULL || GID_GetName == NULL || GID_GetSex == NULL || GID_GetSexGB == NULL || GID_GetBirth == NULL || GID_GetAddr == NULL || GID_GetIDNum == NULL || GID_GetDep == NULL || GID_GetBegin == NULL || GID_GetEnd == NULL || GID_GetPassPortId == NULL || GID_SignCount == NULL || GID_GetCardType == NULL){return "-1^RdCard.dll函数获取失败";}return "";
}/// <summary>
/// 去除两边空白字符
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
char* TrimStr(char* str)
{char* head = str;while (*head == ' '){++head;}char* end = head + strlen(head) - 1;while (*end == ' '){--end;}*(end + 1) = 0;strcpy(str, head);return str;
}/// <summary>
/// 读身份证方法
/// </summary>
/// <returns></returns>
const char* LISReadIDCard()
{//初始化方法const char* initret = InitFunc();if (initret != ""){return initret;}//连接设备unsigned char cmd = 0x41;int para0 = 0, para1 = 8811, para2 = 9986;int ret = UCommand1(&cmd, &para0, &para1, &para2);if (ret != 62171){return "-1^设备连接失败,请检查设备是否插好!";}//验证卡(寻卡)cmd = 0x43;ret = UCommand1(&cmd, &para0, &para1, &para2);//读卡cmd = 0x49;ret = UCommand1(&cmd, &para0, &para1, &para2);if (ret != 62171 && ret != 62172 && ret != 62173 && ret != 62174){return "-1^读卡失败!";}char NameEn[250] = { 0 };char Name[250] = { 0 };char Gender[250] = { 0 };char Nation[250] = { 0 };char BirthDate[250] = { 0 };char Address[250] = { 0 };char IDNumber[250] = { 0 };char SignOrgan[250] = { 0 };char BeginTerm[250] = { 0 };char ValidTerm[250] = { 0 };char NewAddress[250] = { 0 };char PassPortId[250] = { 0 };char SignCount[250] = { 0 };char CardType[250] = { 0 };char CardVersion[250] = { 0 };switch (ret){//二代证case 62171:{GetName(Name);GetSexGB(Gender);GetFolkGB(Nation);GetBirth(BirthDate);GetAddr(Address);GetIDNum(IDNumber);GetDep(SignOrgan);GetBegin(BeginTerm);GetEnd(ValidTerm);GetNewAddr(NewAddress);break;}//二代证带指纹case 62172:{GetName(Name);GetSexGB(Gender);GetFolkGB(Nation);GetBirth(BirthDate);GetAddr(Address);GetIDNum(IDNumber);GetDep(SignOrgan);GetBegin(BeginTerm);GetEnd(ValidTerm);GetNewAddr(NewAddress);break;}//外国人case 62173:{FID_GetEnName(NameEn);FID_GetChName(Name);FID_GetSexGB(Gender);if ((unsigned char)Gender[0] == 0xC4 && (unsigned char)Gender[1] == 0xD0){strcat(Gender, " / M");}if ((unsigned char)Gender[0] == 0xC5 && (unsigned char)Gender[1] == 0xAE){strcat(Gender, " / F");}char temp[256] = { 0 };FID_GetChNationality(temp);char temp1[256] = { 0 };FID_GetNationality(temp1);sprintf_s(Nation, "%s / %s", temp, temp1);FID_GetBirth(BirthDate);FID_GetIDNum(IDNumber);strcpy(SignOrgan, "公安部 / Ministry of Public Security");FID_GetBegin(BeginTerm);FID_GetEnd(ValidTerm);char version[32] = { 0 };FID_GetVersion(version);strcpy(CardVersion, version);break;}//港澳台case 62174:{GID_GetName(Name);GID_GetSexGB(Gender);GID_GetBirth(BirthDate);GID_GetAddr(Address);GID_GetIDNum(IDNumber);GID_GetDep(SignOrgan);GID_GetBegin(BeginTerm);GID_GetEnd(ValidTerm);GID_GetPassPortId(PassPortId);GID_SignCount(SignCount);GID_GetCardType(CardType);break;}}//关闭读卡器cmd = 0x42;UCommand1(&cmd, &para0, &para1, &para2);//组串返回const char* retStr = (string(TrimStr(NameEn)) + "^" + string(TrimStr(Name)) + "^" + string(TrimStr(Gender)) + "^" + string(TrimStr(Nation)) + "^" + string(TrimStr(BirthDate)) + "^" + string(TrimStr(Address)) + "^" + string(TrimStr(IDNumber)) + "^" + string(TrimStr(SignOrgan)) + "^" + string(TrimStr(BeginTerm)) + "^" + string(TrimStr(ValidTerm)) + "^" + string(TrimStr(NewAddress)) + "^" + string(TrimStr(PassPortId)) + "^" + string(TrimStr(SignCount)) + "^" + string(TrimStr(CardType)) + "^" + string(TrimStr(CardVersion))).c_str();return retStr;
}/// <summary>
/// 以exe编译时候测试的主方法
/// </summary>
/// <returns></returns>
int main()
{string info = LISReadIDCard();cout << info << endl;//停住getchar();return 0;
}

该项目先编译成exe控制台测试可不可以读身份证。如果控制台好使了再编译成dll供C#调用。这里碰到一个坑是我以Debug模式编译的exe到没开发环境的电脑就算安装VC2015运行时还报错。后面宏伟兄发现我是Debug编译导致的。由于之前一直用C#写,C#的Debug编译没影响,所以不知道还要这出(这里要记得以Release模式编译额)。

然后碰到的问题就是开始C++包装的方法返回string。然后在C#用String接返回值程序会崩溃。

这里给C++方法返回改为const char*(即字符串指针),然后C#用IntPtr接指针,然后从指针取字符串数据。

C#包装如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using ReadCardService;namespace HLJHYZYYReadCard
{public class ReadCard : IReadCard{/// <summary>/// 读身份证/// </summary>/// <returns></returns>[DllImport("LISReadCard.dll")]public static extern IntPtr LISReadIDCard();/// <summary>/// 读卡1-就诊卡,2-医保卡,3-身份证/// </summary>/// <param name="type">卡类型</param>/// <returns></returns>public string Read(string type){IntPtr ret = LISReadIDCard();string str = Marshal.PtrToStringAnsi(ret);if (str.Substring(0, 3) == "-1^"){return "";}str = str.Replace("^","&");return str;}}
}

最终把接口实现配置到公共读卡程序里,让程序通过反射加载调用,程序再模拟条码枪,就把身份证读卡模拟为扫码操作了,界面只要实现回车事件处理即可。

最终刷一次就等于一次扫码

总算是把C++和C#结合用起来了,积累、成长、坚持

神思通用100型读身份证相关推荐

  1. 阿里云u1服务器通用算力型CPU处理器性能测评

    阿里云服务器u1通用算力型Universal实例高性价比,CPU采用Intel(R) Xeon(R) Platinum,主频是2.5 GHz,云服务器U1实例的基准vCPU算力与5代企业级实例持平,最 ...

  2. 重生之我测阿里云U1实例(通用算力型实例)

    官方福利!!!!大厂羊毛你确定不薅??? 参与ECSU实例评测,申请免费体验机会:https://developer.aliyun.com/mission/review/ecsu 参与ECSU实例评测 ...

  3. 阿里云新品通用算力型u1实例云服务器怎么样?适用于哪些场景?

    阿里云通用算力型实例提供均衡的计算.内存和网络资源,支持多种处理器和多种处理器内存配比.该类型实例依托阿里云定制的CPU调度器.智能负载感知和智能调度算法进行动态资源管理,基于实例规格和应用负载为实例 ...

  4. 阿里云通用算力型u1实例规格介绍(实例特点、适用场景、指标数据)

    阿里云在2022金秋云创季活动中新增了一个通用算力型u1实例规格的云服务器,这是最新产品,本文介绍云服务器ECS通用算力型实例规格族的特点,并列出了具体的实例规格. 一.通用算力型实例介绍 通用算力型 ...

  5. 棋牌游戏通用牌型数值化方案

    棋牌游戏通用牌型数值化方案 1. 数值化方案背景: 游戏中,要对各个玩家的牌进行比较,排序.通常情况下,我们会这样组织数据: BYTE cbCardData[PlayerCount][CardCoun ...

  6. TOP 100值得读的图神经网络----自监督学习与预训练

    清华大学的Top 100 GNN papers,其中分了十个方向,每个方向10篇.此篇为自监督学习与预训练方向的阅读笔记. Top100值得一读的图神经网络| 大家好,我是蘑菇先生,今天带来Top10 ...

  7. 明华澳汉读卡器安装插件,便捷读身份证,就诊卡医保卡

    可以方便的读身份证,就诊卡-磁条卡-CPU-M1卡-4442卡-社保卡等,JS就能读取. 我放资源里了,不要分.https://download.csdn.net/download/wybshyy/8 ...

  8. android使用精伦身份证读卡器读身份证

    使用的设备是iDR210 1.加上权限 <uses-feature android:name="android.hardware.usb.host" /><use ...

  9. 一文搞懂文本识别、银行卡识别、通用卡证识别、身份证识别

    1 前言   查看华为开发者联盟网站的机器学习服务业务介绍(https://developer.huawei.com/consumer/cn/doc/development/HMS-Guides/ml ...

最新文章

  1. 【转载】C语言变量详解
  2. 虚拟电脑键盘app_说到弹吉他,这几个APP你一定用得上
  3. 【转】 浏览器分析模拟登陆过程
  4. 【NLP】推荐一些NER的英文数据集
  5. java中的json_java中的json使用
  6. 在死循环中使用Scanner获得键盘输入
  7. 启动zookeeper_架构设计 | 分布式系统调度,Zookeeper集群化管理
  8. string类常用单字符处理函数
  9. Cobalt Strike参数详解
  10. java.lang.ArrayIndexOutOfBoundsException 索引越界异常
  11. python按键盘上哪个键运行_python键盘操作PyKeyboard安装使用详解
  12. 调用ArcGIS Server的GP服务,显示No JSON object could be decoded要怎么解决?
  13. 骗子QQ2875827910手机号码15591473507微信号gewen521520
  14. html div background-image,css3背景background-image
  15. Docker安装配置Redis最全教程
  16. 简单说 用CSS做一个魔方旋转的效果
  17. 浅析jQuery删除节点的三个方法
  18. ECCV2020:夜晚深度图估计
  19. 使用打码平台登录B站
  20. spring不停机部署_spring cloud 学习(7) - 生产环境如何不停机热发布? - 菩提树下的杨过 - 博客园...

热门文章

  1. 传智播客成都java培训老学员福利
  2. Invitation Cards POJ - 1511【最短路】
  3. 分享一个源代码:微信电影票预订(微信小程序版)
  4. JavaScript---开通QQ在线客服
  5. 【基础教程】Python整数类型(int)详解
  6. 怎么知道自己适合做什么?
  7. csgo搬砖是什么?我们如何操作赚钱?
  8. 快速搭建迅搜搜索引擎步骤
  9. 所见即所得网页html编辑器,在线所见即所得HTML编辑器的实现原理浅析
  10. 今年来,知识分享与内容付费趋势已经暗潮汹涌