需求来源
由于使用Electron使用开发桌面端,同时也需要连接硬件设备,单纯使用js方法无法完成,需要通过Node调用dll动态库方式完成。
版本说明:
- node v12.18.3 (32位)
- npm 6.14.6
- python 2.7.15 (3.x版本不支持)
注意事项
- dll动态库在windows系统下才能使用
- dll动态库和node同时都是32位,或者都是64位,一般情况下会使用32位,这样能兼容到64位系统。
- node 版本<10 && Electron < 6时,使用node-ffi;node版本>=10 && Electron >=6时,使用nodt-ffi-napi
安装依赖
安装ffi依赖时需要以下环境:
- python2.x (python3.x版本不支持),安装完成后设置环境变量
- .net framework 4.5.1
- visual C++ Build Tools
-- 以管理员身份运行:
npm install -global --production windows-build-tools
npm install -global node-gyp
cd 到项目目录中安装ffi
npm install ffi-napi --save
ffi调用
- 创建一个app.js文件
- 把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)
- 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 |
- 返回值
- 0x90 读机读文字信息和相片信息成功;
- 其它 读机读文字信息和相片信息失败
// 调用 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)
}
- 读取身份证信息后需要把buffer类型转为中文
- 安装依赖库
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