Node.js 调用 dll动态库 以华旭身份证阅读器为例

需求来源

由于使用Electron使用开发桌面端,同时也需要连接硬件设备,单纯使用js方法无法完成,需要通过Node调用dll动态库方式完成。

版本说明:

  1. node v12.18.3 (32位)
  2. npm 6.14.6
  3. python 2.7.15 (3.x版本不支持)

注意事项

  1. dll动态库在windows系统下才能使用
  2. dll动态库和node同时都是32位,或者都是64位,一般情况下会使用32位,这样能兼容到64位系统。
  3. node 版本<10 && Electron < 6时,使用node-ffi;node版本>=10 && Electron >=6时,使用nodt-ffi-napi

安装依赖

安装ffi依赖时需要以下环境:
  1. python2.x (python3.x版本不支持),安装完成后设置环境变量
  2. .net framework 4.5.1
  3. visual C++ Build Tools
-- 以管理员身份运行:
npm install -global --production windows-build-tools
npm install -global node-gyp
cd 到项目目录中安装ffi
npm install ffi-napi --save

ffi调用

  1. 创建一个app.js文件
  2. 把HxgcDeviceApi_J10.dll拷贝到项目目录中,这里以华旭身份证阅读器为例
--- app.js
//引入ffi-napi
const ffi = require('ffi-napi')

//加载动态库

const hxgc = new ffi.Library('HxgcDeviceApi_J10',{
    
    
    // CarderOpen为调用方法名,第一个int32为返回值类型,
    // 第二、第三个int32为参数值类型
    'CarderOpen':['int32',['int32','int32']],
    'GetModuleVer':['int',['int','string']],
    'SDT_OpenPort':['int32',['int32']],
    'SDT_ResetSAM':['int32',['int32','int32']],
    'SDT_ReadBaseMsg':['int32',['int32','string','int32','string','int32','int32']]
  })
  
//调用方法
const result = hxgc.CarderOpen(1001,115200)

  1. HxgcDeviceApi_J10.dll 有一个方法为 ‘SDT_ReadBaseMsg’
int __stdcall SDT_ReadBaseFPMsg( int iPort ,
                              unsigned char* pucCHMsg ,
                              unsigned int* puiCHMsgLen ,
                              unsigned char* pucPHMsg ,
                              unsigned int* puiPHMsgLen, 
                              unsigned char* pucFPMsg, 
                              unsigned int* puiFMsgLen, 
                              int iIfOpen );
  • 参数说明
编号 参数名 说明
1 iPort 输入参数,整数,表示端口号
2 pucCHMsg 输出参数,无符号字符型指针,指向读到的文字信息,其长度由puiCHMsgLen参数输出。该指针指向的存储空间由调用者分配,不得小于256字节。
3 puiCHMsgLen 输出参数,无符号整型数指针,指向读到的文字信息长度,最长256字节。
4 pucPHMsg 输出参数,无符号字符型指针,指向读到的相片信息,其长度由puiPHMsgLen参数输出。该指针指向的存储空间由调用者分配,不得小于1024字节。
5 puiPHMsgLen 输出参数,无符号整型数指针,指向读到的相片信息长度,最长1024字节。
6 pucFPMsg 输出参数,无符号字符型指针,指向读到的指纹信息,其长度由puiFPMsgLen参数输出。该指针指向的存储空间由调用者分配,不得小于1024字节。
7 puiFMsgLen 输出参数,无符号整型数指针,指向读到的指纹信息长度,最长1024字节。
8 iIfOpen 输入参数,整数,参见SDT_ResetSAM
  • 返回值
  1. 0x90 读机读文字信息和相片信息成功;
  2. 其它 读机读文字信息和相片信息失败
// 调用 SDT_ReadBaseFPMsg 获取身份证基本信息
//个人基本信息
const byCHMsg = Buffer.alloc(256+1)
//照片信息
const byPHMsg = Buffer.alloc(1024+1)

const res = hxgc.SDT_ReadBaseMsg(1001,byCHMsg,0,byPHMsg,0,1)
//16进制0x90转换10进制为144
if (res == 144) {
    
    
    //读取成功
    console.log(byCHMsg)
}
  1. 读取身份证信息后需要把buffer类型转为中文
  2. 安装依赖库
npm install iconv-lite --save
// 引入依赖库 
const iconv = require('iconv-lite')

//定义个人基本信息属性
const name = Buffer.alloc(30)
const sex = Buffer.alloc(2)
const race = Buffer.alloc(4)
const birth = Buffer.alloc(16)
const address = Buffer.alloc(70)
const id = Buffer.alloc(36)
const company = Buffer.alloc(30)
const beginDate = Buffer.alloc(16)
const endDate = Buffer.alloc(16)
//把个人基本信息复制到各个属性中
byCHMsg.copy(name,0,0,30)
byCHMsg.copy(sex,0,30,32)
byCHMsg.copy(race,0,32,36)
byCHMsg.copy(birth,0,36,52)
byCHMsg.copy(address,0,52,122)
byCHMsg.copy(id,0,122,158)
byCHMsg.copy(company,0,158,188)
byCHMsg.copy(beginDate,0,188,204)
byCHMsg.copy(endDate,0,204,220)

//输出中文
console.log('name:'+iconv.decode(name,'utf16'))
console.log('sex:'+iconv.decode(sex,'utf16'))
console.log('race:'+iconv.decode(race,'utf16'))
console.log('birth:'+iconv.decode(birth,'utf16'))
console.log('address:'+iconv.decode(address,'utf16'))
console.log('id:'+iconv.decode(id,'utf16'))
console.log('company:'+iconv.decode(company,'utf16'))
console.log('beginDate:'+iconv.decode(beginDate,'utf16'))
console.log('endDate:'+iconv.decode(endDate,'utf16'))

运行

node app.js

下载demo

猜你喜欢

转载自blog.csdn.net/qq_18944765/article/details/107913125