前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用jnative调用c语言动态库对接华视电子身份证阅读机

使用jnative调用c语言动态库对接华视电子身份证阅读机

作者头像
周杰伦本人
发布2022-10-25 16:06:18
9480
发布2022-10-25 16:06:18
举报
文章被收录于专栏:同步文章

一 身份证阅读器SDK使用手册

1. 定义

应用函数开发包含下列文件: termb.dll API函数的动态联接库 sdtapi.dll 安全模块通讯函数 UnPack.dll 身份证相片解码库 适用操作系统: Windows NT: 需要NT 3.1版或以后版本 Windows: 需要 Windows 98、Windows 2000或以后版本 适用开发语言: Visual C++ 5.0 及以后版本 Visual Basic 5.0 及以后版本 Delphi 3.0 及以后版本 PowerBuilder 6.0 及以后版本

2. 函数列表

//以下为主要API函数 int CVR_InitComm(int Port) 初始化连接; int CVR_Authenticate() 卡认证; int CVR_Read_Content(int active) 读卡操作。 int CVR_CloseComm() 关闭连接;

//以下为可选API函数,方便二次开发 int GetPeopleName(char *strTmp, int *strLen) 得到姓名信息 int GetPeopleSex(char *strTmp, int *strLen) 得到性别信息 int GetPeopleNation(char *strTmp, int *strLen) 得到民族信息 int GetPeopleBirthday(char *strTmp, int *strLen) 得到出生日期 int GetPeopleAddress(char *strTmp, int *strLen) 得到地址信息 int GetPeopleIDCode(char *strTmp, int *strLen) 得到身份证号信息 int GetDepartment(char *strTmp, int *strLen) 得到发证机关信息 int GetStartDate(char *strTmp, int *strLen) 得到有效开始日期 int GetEndDate(char *strTmp, int *strLen) 得到有效截止日期 int CVR_GetSAMID(char *SAMID) 得到安全模块号

3. 函数说明

初始化连接

原 型:int CVR_InitComm (int Port) 说 明:本函数用于PC与华视电子第二代居民身份证阅读器的连接。 参 数:Port:连接串口(COM1COM16)或USB口(10011016) 值 意义 1 串口1 2 串口2 3 串口3 4 串口4 1001 USB口1 1002 USB口2 1003 USB口3 1004 USB口4

返 回 值: 值 意义 1 正确 2 端口打开失败 0 动态库加载失败

关闭串口

原 型: int CVR_CloseComm(void) 说 明:本函数用于关闭PC到阅读器的连接。 参 数:无 返 回 值: 值 意义 1 正确 0 错误

卡认证

原 型:int CVR_Authenticate (void) 说 明:本函数用于读卡器和卡片之间的合法身份确认。卡认证循环间隔大于300ms。 参 数: 返 回 值: 值 意义 说明 1 正确 卡片认证成功 2 错误 寻卡失败 3 错误 选卡失败 0 错误 初始化失败 注意:若卡片放置后发生认证错误时,应移走卡片重新放置。

读卡操作

原 型:int CVR_Read_Content(int active); 说 明:本函数用于通过阅读器从第二代居民身份证中读取相应信息。卡认证成功以后才可做读卡操作,读卡完毕若继续读卡应移走二代证卡片重新放置做卡认证。 参 数:active:兼容以前版本,无实际意义

返 回 值: 返回值 意义 1 正确 0 错误 99 异常 说明: 读卡成功后在termb.dll文件所在路径下生成wz.txt(文字信息)和zp.bmp(照片信息) wz.txt内容示例如下: 张红叶 女 汉 1988-11-18 河北省邯郸市临漳县称勾镇称勾东村复兴路25号 130423198811184328 临漳县公安局 2011.03.30-2021.03.30

读各项文字信息到自定义内存缓冲

原 型: int GetPeopleName(char *strTmp, int *strLen) //得到姓名信息 int GetPeopleSex(char *strTmp, int *strLen) //得到性别信息 int GetPeopleNation(char *strTmp, int *strLen) //得到民族信息 int GetPeopleBirthday(char *strTmp, int *strLen) //得到出生日期 int GetPeopleAddress(char *strTmp, int *strLen) //得到地址信息 int GetPeopleIDCode(char *strTmp, int *strLen) //得到卡号信息 int GetDepartment(char *strTmp, int *strLen) //得到发证机关信息 int GetStartDate(char *strTmp, int *strLen) //得到有效开始日期 int GetEndDate(char *strTmp, int *strLen) //得到有效截止日期 int CVR_GetSAMID(char * SAMID) //得到安全模块号码 参数: *strTmp 返回的信息缓存指针。 *strLen 返回的信息长度指针。 返 回 值: 返回值 意义 1 正确 0 错误

注意:若采用查询方式自动判断卡片是否放置,则间隔时间建议大于300ms。

二 开始对接

主要做的功能就是使用身份证刷卡登录系统

大致流程是这样的: 前端是定时请求后台 后台流程就是

  1. 初始化连接
  2. 卡认证
  3. 读卡操作
  4. 得到身份证号信息

然后拿到这个身份证号后与数据库的用户对应身份证对比一下 如果相同 就调转到主页 完成登录

jnative 使用套路的话就是把用到的dll文件放到jdk的bin目录下面

动态链接库编译时选择的平台。如果通过x86平台编译,那么只能使用32位jdk环境加载,如果要使用64位jdk,必须使用x64平台编译。

那么怎么看dll文件是32位还是64位呢 可以装一个Visual Studio 自带工具dumpbin.exe 执行dumpbin.exe /headers 文件路径 像这样:

在这里插入图片描述
在这里插入图片描述

jnative 用法:

代码语言:javascript
复制
JNative n = null;
		try
		{
			n = new JNative("Termb.dll", "CVR_InitComm");
			n.setRetVal(Type.INT); // 指定返回参数的类型
			n.setParameter(0, Port);//设置参数
			n.invoke(); // 调用方法
			return Integer.parseInt(n.getRetVal());//得到返回值
		}
		finally
		{

		}

实例:

引入jar包

代码语言:javascript
复制
	<dependency>
          <groupId>org.apache</groupId>
          <artifactId>JNative</artifactId>
          <version>1.0.0</version>
      </dependency>

后台代码:

代码语言:javascript
复制
		//1.打开端口
		int portReturnCode =1001;
		try
		{
			portReturnCode = CVR_InitComm(Integer.parseInt(intport));
			logger.info("打开端口返回值:" + String.valueOf(portReturnCode));
			if (portReturnCode!=1) {
				return null;
			}
		}
		catch(Exception ex)
		{
			logger.error("打开端口调用异常!"+ ex.getMessage());
		}

		// 2. 认证
		int authReturnCode = 0;
		try
		{
			authReturnCode = CVR_Authenticate();
			logger.info("认证返回值:" + String.valueOf(authReturnCode));
			if (authReturnCode!=1) {
				return null;
			}
		}
		catch(Exception ex)
		{
			logger.error("认证调用异常!"+ ex.getMessage());
		}

		//3. 读卡
		int readReturnCode = 0;
		try
		{
			readReturnCode = CVR_Read_Content(4);
			logger.info("读卡返回值:" + String.valueOf(readReturnCode));
			if (authReturnCode!=1) {
				return null;
			}
		}
		catch(Exception ex)
		{
			logger.error("读卡调用异常!"+ ex.getMessage());
		}

		//4. 读取身份证号码
		int readIdReturnCode = 0;
		try
		{
			readIdReturnCode = GetPeopleIDCode();
			logger.info("读取身份证号码返回值:" + String.valueOf(readIdReturnCode));
			if(readIdReturnCode == 1)
			{
				logger.info("身份号码:" + strTmp.trim());

			}
		}
		catch(Exception ex)
		{
			logger.error("调用异常!"+ ex.getMessage());
		}
		return strTmp.trim();
	}

调用动态库的方法:

代码语言:javascript
复制
	/**
	 * 身份证阅读机打开端口
	 * @param Port
	 * @return
	 * @throws NativeException
	 * @throws IllegalAccessException
	 * @throws UnsupportedEncodingException
	 */
	private  int CVR_InitComm(int Port) throws NativeException, IllegalAccessException, UnsupportedEncodingException
	{
		JNative n = null;
		try
		{
			n = new JNative("Termb.dll", "CVR_InitComm");
			n.setRetVal(Type.INT); // 指定返回参数的类型
			n.setParameter(0, Port);
			n.invoke(); // 调用方法
			return Integer.parseInt(n.getRetVal());
		}
		finally
		{

		}
	}

	/**
	 * 身份证阅读机认证
	 * @return
	 * @throws NativeException
	 * @throws IllegalAccessException
	 */
	private  int CVR_Authenticate() throws NativeException, IllegalAccessException
	{
		JNative n = null;
		try
		{
			n = new JNative("Termb.dll", "CVR_Authenticate");
			n.setRetVal(Type.INT); // 指定返回参数的类型
			n.invoke(); // 调用方法
			return Integer.parseInt(n.getRetVal());
		}
		finally
		{

		}
	}

	/**
	 * 身份证阅读机读卡
	 * @return
	 * @throws NativeException
	 * @throws IllegalAccessException
	 */
	private  int CVR_Read_Content(int Active) throws NativeException, IllegalAccessException
	{
		JNative n = null;
		try
		{
			n = new JNative("Termb.dll", "CVR_Read_Content");
			n.setRetVal(Type.INT); // 指定返回参数的类型
			n.setParameter(0, Active);
			n.invoke(); // 调用方法
			return Integer.parseInt(n.getRetVal());
		}
		finally
		{

		}
	}

	/**
	 * 身份证阅读机获取身份证号
	 * @return
	 * @throws NativeException
	 * @throws IllegalAccessException
	 */
	private  int GetPeopleIDCode() throws NativeException, IllegalAccessException
	{
		JNative n = null;
		try
		{
			n = new JNative("Termb.dll", "GetPeopleIDCode");
			n.setRetVal(Type.INT); // 指定返回参数的类型
			Pointer a = new Pointer(MemoryBlockFactory.createMemoryBlock(4*10));
			Pointer b = new Pointer(MemoryBlockFactory.createMemoryBlock(4*30));
			n.setParameter(0,b);
			n.setParameter(1,a);
			n.invoke();
			byte[] by = new byte[120];
			by = b.getMemory();
			try
			{
				strTmp = new String(by,"gb2312");
			}
			catch (UnsupportedEncodingException ex)
			{
				logger.error("获取身份信息异常:",ex);
			}

			int asInt = a.getAsInt(0);

			a.dispose();
			b.dispose();
			return Integer.parseInt(n.getRetVal());
		}
		finally
		{

		}
	}

附上一个demo: https://github.com/xiepanpan/CVR100Demo

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-05-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 身份证阅读器SDK使用手册
    • 1. 定义
      • 2. 函数列表
        • 3. 函数说明
          • 初始化连接
          • 关闭串口
          • 卡认证
          • 读卡操作
          • 读各项文字信息到自定义内存缓冲
      • 二 开始对接
        • 实例:
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档