在项目上经常要用到身份证阅读器、护照阅读仪、指纹仪等各种品牌硬件,假如每套系统的都做集成开发那代码的维护成本将变得很高,为此采用rust来调用厂家提供的sdk c++开发包并封装成nodejs包,用fastify来开发成web api独立的服务形式。这样我们开发系统时只需调用web接口即可,跨平台又可共用,方便快捷,话不多说来看代码如何实现。
安装rust后,打开vs新建一个工程目录,我们通过cargo new创建的一个package项目,加上--lib参数后创建的项目就是库项目(library package)。
cargo new --lib reader
package 就是一个项目,因此它包含有独立的 Cargo.toml 文件,用于项目配置。库项目只能作为三方库被其它项目引用,而不能独立运行,即src/lib.rs。
典型的package
如果一个 package 同时拥有 src/main.rs 和 src/lib.rs,那就意味着它包含两个包:库包和二进制包,这两个包名也都是 test_math —— 都与 package 同名。
一个真实项目中典型的 package,会包含多个二进制包,这些包文件被放在 src/bin 目录下,每一个文件都是独立的二进制包,同时也会包含一个库包,该包只能存在一个 src/lib.rs:
.
├── Cargo.toml
├── Cargo.lock
├── src
│ ├── main.rs
│ ├── lib.rs
│ └── bin
│ └── main1.rs
│ └── main2.rs
├── tests
│ └── some_integration_tests.rs
├── benches
│ └── simple_bench.rs
└── examples
└── simple_example.rs
- use std::collections::HashMap;
- use libc::{c_int, c_void};
- use libloading::{Library, Symbol};
- use neon::prelude::*;
- use once_cell::sync::OnceCell;
- use serde::Serialize;
- extern crate encoding;
- use encoding::all::GB18030;
- use encoding::{DecoderTrap,EncoderTrap,Encoding};
- use widestring::{WideCStr, WideCString, WideChar};
- // 编码转换 utf8 -> utf16le
- fn encode(source: &str) -> WideCString {
- let string_source = source.to_string() + "\0";
- WideCString::from_str(&string_source).unwrap()
- }
- // 解码转换 utf16le -> utf8
- fn decode(source: &[WideChar]) -> String {
- WideCStr::from_slice_truncate(source)
- .unwrap()
- .to_string()
- .unwrap()
- }
- // 加载 dll
- static LIBRARY: OnceCell<Library> = OnceCell::new();
- static MACHINE_KIND: &str = if cfg!(target_os = "windows") {
- if cfg!(target_arch = "x86") {
- "win32"
- } else if cfg!(target_arch = "x86_x64") {
- "win64"
- } else {
- "other"
- }
- } else if cfg!(target_os = "linux") {
- if cfg!(target_arch = "x86") {
- "linux32"
- } else if cfg!(target_arch = "x86_64") {
- "linux64"
- } else if cfg!(target_arch = "aarch64") {
- "aarch64"
- } else if cfg!(target_arch = "arm") {
- "arm"
- } else {
- "other"
- }
- } else {
- "other"
- };
- //设置识别的证件 ID
- // 设置当前要识别的证件类型,并将
- // 之前已经设置的证件类型清除。
- // nMainID 主要识别类型,nSubID 子类型
- // nSubID 头指针,默认将数组
- // nSubID 第 一 个 元 素 赋 值 为 0 即
- // nSubID[0]=0
- // type S = c_int[];
- type LPCTSTR = *const WideChar;
- type BOOL = c_int;
- type INITPTR = *const i8;
- type CANRST = *mut WideChar;
- // 打开设备
- type S2V7_open = unsafe extern "system" fn() -> c_int;
- // 关闭设备
- type S2V7_close = unsafe extern "system" fn() -> c_int;
- //【set mode 设置读证功能】
- type S2V7_set_mode =
- unsafe extern "system" fn(flg_takeColor: c_int, flg_takeUV: c_int, flg_readChipInfo: c_int, flg_readChipFace: c_int) -> c_int; // Type = 0 即可
- //【wait Doc. in 等待放卡】
- type S2V7_wait_DocIn =
- unsafe extern "system" fn(timeout: f64, flg_in: INITPTR) -> c_int; // Type = 0 即可
- //【wait Doc. out 等待拿卡】
- type S2V7_wait_DocOut =
- unsafe extern "system" fn(timeout: f64, flg_out: INITPTR) -> c_int; // Type = 0 即可
- //【process 执行读卡过程】
- type S2V7_process = unsafe extern "system" fn() -> c_int;
- //读取卡类型
- type S2V7_get_cardType = unsafe extern "system" fn() -> c_int;
- //保存彩照
- type S2V7_VIS_saveColor = unsafe extern "system" fn(imgPath: LPCTSTR) -> c_int;
- //保存红外照
- type S2V7_VIS_saveIR = unsafe extern "system" fn(imgPath: LPCTSTR) -> c_int;
- //【get MRZ text 获取OCR文字信息】
- type S2V7_VIS_getMRZtext = unsafe extern "system" fn(text: LPCTSTR) -> c_int;
- //show text information 文字信息
- type S2V7_RDO_getBytesByIndex = unsafe extern "system" fn(index: c_int,data: LPCTSTR) -> c_int;
- type S2V7_VIS_getBytesByIndex = unsafe extern "system" fn(index: c_int,data: LPCTSTR) -> c_int;
- type S2V7_RF_active = unsafe extern "system" fn(antenna: c_int,atr: LPCTSTR, atr_len: c_int) -> c_int;
- static V7_OPEN: OnceCell<Symbol<S2V7_open>> = OnceCell::new();
- static V7_CLOSE: OnceCell<Symbol<S2V7_close>> = OnceCell::new();
- static V7_SET_MODE: OnceCell<Symbol<S2V7_set_mode>> = OnceCell::new();
- static V7_WAIT_DOCINT: OnceCell<Symbol<S2V7_wait_DocIn>> = OnceCell::new();
- static V7_WAIT_DOCOUT: OnceCell<Symbol<S2V7_wait_DocOut>> = OnceCell::new();
- static V7_PROCESS: OnceCell<Symbol<S2V7_process>> = OnceCell::new();
- static V7_GET_CARDTYPE: OnceCell<Symbol<S2V7_get_cardType>> = OnceCell::new();
- static V7_VIS_SAVECOLOR: OnceCell<Symbol<S2V7_VIS_saveColor>> = OnceCell::new();
- static V7_VIS_SAVEIR: OnceCell<Symbol<S2V7_VIS_saveIR>> = OnceCell::new();
- static V7_VIS_GETMRZTEXT: OnceCell<Symbol<S2V7_VIS_getMRZtext>> = OnceCell::new();
- static V7_RDO_getBytesByIndex: OnceCell<Symbol<S2V7_RDO_getBytesByIndex>> = OnceCell::new();
- static V7_VIS_getBytesByIndex: OnceCell<Symbol<S2V7_VIS_getBytesByIndex>> = OnceCell::new();
- static V7_RF_active: OnceCell<Symbol<S2V7_RF_active>> = OnceCell::new();
- // static
- static mut INITDLL: bool = false;
- static mut DEVICE_START_INDEX: u64 = 0;
- static mut DIRECTORY_PATH: OnceCell<String> = OnceCell::new();
- static mut USER_ID: OnceCell<String> = OnceCell::new();
- static mut DEVCIE_NAME: OnceCell<String> = OnceCell::new();
- static mut RESULT_TYPE: OnceCell<i32> = OnceCell::new();
- static mut NEED_RECORD: OnceCell<bool> = OnceCell::new();
- // 初始化dll
- fn init_dll(dll_path: &str) -> Result<bool, Box<dyn std::error::Error>> {
- unsafe {
- if INITDLL {
- return Ok(true);
- }
- }
- println!("加载dll");
- println!("dll_path");
- let library = LIBRARY.get_or_init(|| unsafe { Library::new(dll_path).unwrap() });
- println!("S2V7_open");
- V7_OPEN.get_or_init(|| unsafe { library.get::<S2V7_open>(b"S2V7_open").unwrap() });
- println!("S2V7_close");
- V7_CLOSE.get_or_init(|| unsafe { library.get::<S2V7_close>(b"S2V7_close").unwrap() });
- println!("S2V7_set_mode");
- V7_SET_MODE.get_or_init(|| unsafe {library.get::<S2V7_set_mode>(b"S2V7_set_mode").unwrap()});
- println!("S2V7_wait_DocIn");
- V7_WAIT_DOCINT.get_or_init(|| unsafe { library.get::<S2V7_wait_DocIn>(b"S2V7_wait_DocIn").unwrap() });
- println!("S2V7_wait_DocOut");
- V7_WAIT_DOCOUT.get_or_init(|| unsafe { library.get::<S2V7_wait_DocOut>(b"S2V7_wait_DocOut").unwrap() });
- V7_PROCESS.get_or_init(|| unsafe { library.get::<S2V7_process>(b"S2V7_process").unwrap() });
- V7_GET_CARDTYPE.get_or_init(|| unsafe { library.get::<S2V7_get_cardType>(b"S2V7_get_cardType").unwrap() });
- V7_VIS_SAVECOLOR.get_or_init(|| unsafe { library.get::<S2V7_VIS_saveColor>(b"S2V7_VIS_saveColor").unwrap() });
- V7_VIS_SAVEIR.get_or_init(|| unsafe { library.get::<S2V7_VIS_saveIR>(b"S2V7_VIS_saveIR").unwrap() });
- V7_VIS_GETMRZTEXT.get_or_init(|| unsafe { library.get::<S2V7_VIS_getMRZtext>(b"S2V7_VIS_getMRZtext").unwrap() });
- V7_RDO_getBytesByIndex.get_or_init(|| unsafe { library.get::<S2V7_RDO_getBytesByIndex>(b"S2V7_RDO_getBytesByIndex").unwrap() });
- V7_VIS_getBytesByIndex.get_or_init(|| unsafe { library.get::<S2V7_VIS_getBytesByIndex>(b"S2V7_VIS_getBytesByIndex").unwrap() });
- V7_RF_active.get_or_init(|| unsafe { library.get::<S2V7_RF_active>(b"S2V7_RF_active").unwrap() });
- unsafe {
- INITDLL = true;
- }
- Ok(true)
- }
- fn init() -> c_int {
- let directory = unsafe { DIRECTORY_PATH.get().unwrap() };
- let userid = unsafe { USER_ID.get().unwrap() };
- let directory_path = std::path::Path::new(directory).join(MACHINE_KIND);
- if directory_path.exists() {
- let dll_path = directory_path.join(libloading::library_filename("STAR200_V7_DRV"));
- println!("dll_path: {:?}", dll_path);
- if dll_path.exists() {
- match init_dll(dll_path.to_str().unwrap()).is_ok() {
- true => {
- // 打开设备
- let init_result = unsafe {V7_OPEN.get_unchecked()()};
- if init_result == 0 {
- println!("设备打开成功");
- return ResultType::Success as c_int;
- } else {
- println!("设备打开失败,代码:{:?}",init_result);
- return ResultType::DeviceNotFound as c_int;
- }
- }
- false => {
- return ResultType::INITDLLFail as c_int;
- }
- }
- } else {
- return ResultType::DllPathNotExist as c_int;
- }
- } else {
- println!("{:?}", directory_path);
- return ResultType::DirectoryPathNotExist as c_int;
- }
- }
- pub fn init_by_node(mut cx: FunctionContext) -> JsResult<JsNumber> {
- let directory = cx.argument::<JsString>(0)?.value(&mut cx);
- let userid = cx.argument::<JsString>(1)?.value(&mut cx);
- unsafe {
- DIRECTORY_PATH.take();
- DIRECTORY_PATH.set(directory).unwrap();
- USER_ID.take();
- USER_ID.set(userid).unwrap();
- };
- let result = init() as f64;
- Ok(cx.number(result))
- }
- #[allow(dead_code)] // 允许dead_code
- enum ResultType {
- DirectoryPathNotExist = -2003, // 找不到运行目录
- DllPathNotExist = -2001, // 找不到dll文件
- INITDLLFail = -2000, // 初始化dll
- Success = 0, // 成功
- UserIdFail = 2001, //用户 ID 错误
- DeviceInitFail = 2002, // 设备初始化失败
- DeviceKernelInitFail = 2003, // 初始化核心失败
- DeviceDatInitFail = 2004, //未找到授权文件
- DeviceNotInit = 2101, // 设备未初始化
- DeviceNotFound = 2102, // 没有找到设备
- DeviceReConnect = 2103, // 重新连接设备
- Unknown = -100, // 未知错误
- CheckCardInput = 3001, // 证件放入设备
- CheckCardOut = 3002, // 证件移出设备
- CheckCardNotInOrOut = 3000, // 证件无放入或拿出
- CheckCardBarCode = 3003, // 检测到手机条码
- OCRFail=-1, // 未检测到OCR区域
- }
- type RecogIDCardEXResultItem = HashMap<i32, [String; 2]>;
- #[derive(Default, Serialize)]
- pub struct RecogIDCardEXResultObject {
- pub viz_result: RecogIDCardEXResultItem,
- pub viz_orc_result: RecogIDCardEXResultItem,
- pub mrz_result: RecogIDCardEXResultItem,
- pub mrz_ocr_result: RecogIDCardEXResultItem,
- pub chip_result: RecogIDCardEXResultItem,
- }
- #[derive(Default, Serialize)]
- pub struct RecogIDCardEXResult {
- pub device_name: String,
- pub device_online: bool,
- pub reg_info: RecogIDCardEXResultObject,
- pub img_base64: HashMap<String, String>,
- pub card_type: i32,
- pub record_type: i32,
- pub card_name: String,
- pub success: bool, // 识别是否成功
- }
- static SAVE_IMAGE_REUSLT_NAME: [&str; 5] = [
- "tempHeadEC.jpg",
- "tempHead.jpg",
- "tempUV.jpg",
- "tempIR.jpg",
- "temp.jpg",
- ];
- fn start(mut cx: FunctionContext) -> JsResult<JsUndefined> {
- let callback = cx.argument::<JsFunction>(0)?.root(&mut cx);
- let mut channel = cx.channel();
- channel.reference(&mut cx);
- println!("start {}", channel.has_ref());
- let index = unsafe {
- DEVICE_START_INDEX += 1;
- DEVICE_START_INDEX
- };
- std::thread::spawn(move || {
- // Do the heavy lifting inside the background thread.
- device_start(callback, channel, index);
- });
- Ok(cx.undefined())
- }
- use std::sync::{Arc, Mutex};
- fn device_start(callback: Root<JsFunction>, channel: Channel, index: u64) {
- let index = index;
- let callback = Arc::new(Mutex::new(callback));
- //设置读证功能
- unsafe { V7_SET_MODE.get_unchecked()(1,1,1,1) };
- loop {
- if index != unsafe { DEVICE_START_INDEX } {
- break;
- };
- let callback_clone = Arc::clone(&callback);
- let mut result = RecogIDCardEXResult::default();
- let mut flg_in:i8=0;
- match unsafe { V7_WAIT_DOCINT.get_unchecked()(5.0,&mut flg_in) } {
- // 设备正常 检测是否有放入证件
- 0 => {
- if flg_in==0{
- //检查是否放入超时
- result.record_type = ResultType::CheckCardNotInOrOut as i32;
- break;
- }
- result.device_online = true;
- result.device_name =unsafe { DEVCIE_NAME.get_or_init(|| "".to_string()).to_string() };
-
- match unsafe { V7_PROCESS.get_unchecked()() } {
- // 证件有放入
- 0 => {
- result.record_type = ResultType::CheckCardInput as i32;
- }
- // 未检测到OCR区域
- -1 => {
- result.record_type = ResultType::OCRFail as i32;
- }
- // 未找到非接卡
- // v if v/10 == -21 => {
- // result.record_type = ResultType::OCRFail as i32;
- // }
- // 设备离线
- -3 => {
- result.device_online = false;
- result.record_type = init();
- }
- _ => {
- result.record_type = ResultType::Unknown as i32;
- }
- }
- }
- -3 => {
- //设备离线
- let init = init();
- result.device_online = false;
- result.record_type = init;
- }
- _ => {
- //未知错误
- result.record_type = ResultType::Unknown as i32;
- }
- };
- if unsafe { *NEED_RECORD.get_or_init(|| false) } {
- println!("手工点击识别+1");
- result.record_type = ResultType::CheckCardInput as i32;
- }
- // let time_now = std::time::Instant::now();
- if result.record_type == ResultType::CheckCardInput as i32 {
- let _result = recog_card();
- result.success = _result.success;
- result.img_base64 = _result.img_base64;
- result.reg_info = _result.reg_info;
- result.card_type = _result.card_type;
- result.card_name = _result.card_name;
- }
- let neet_sendinfo = if Some(true) == unsafe { NEED_RECORD.take() } {
- true
- } else {
- false
- };
- // let elapsed = time_now.elapsed();
- // println!("识别时间结束时间 {:.6?}", elapsed);
- if result.record_type != ResultType::CheckCardNotInOrOut as i32
- && (*unsafe { RESULT_TYPE.get_or_init(|| -10000) } != result.record_type
- || result.record_type == ResultType::CheckCardInput as i32
- || neet_sendinfo)
- {
- unsafe {
- RESULT_TYPE.take();
- RESULT_TYPE.set(result.record_type).unwrap();
- }
- channel.send(move |mut cx| {
- let result_json = serde_json::to_string(&result).unwrap();
- let callback = callback_clone.lock().unwrap().to_inner(&mut cx);
- let this = cx.undefined();
- let args = vec![cx.string(&result_json)];
- callback.call(&mut cx, this, args)?;
- Ok(())
- });
- }
- std::thread::sleep(std::time::Duration::from_millis(20));
- }
- }
- // 白光图、红外
- // 图、紫外图、版面头像和芯片头像
- pub fn recog_card() -> RecogIDCardEXResult {
- let time_now = std::time::Instant::now();
- let mut result = RecogIDCardEXResult::default();
- result.device_online = true;
- let img_path_directory = std::path::Path::new(unsafe { DIRECTORY_PATH.get().unwrap() });
- let ir_img_path = img_path_directory.join("ir.jpg");
- let color_img_path = img_path_directory.join("color.jpg");
- //显示红外照
- let irResult = unsafe {V7_VIS_SAVEIR.get_unchecked()(encode(ir_img_path.to_str().unwrap()).as_ptr() as LPCTSTR)};
- //显示彩照
- let colorResult = unsafe {V7_VIS_SAVECOLOR.get_unchecked()(encode(color_img_path.to_str().unwrap()).as_ptr() as LPCTSTR)};
- if irResult==0{
- if ir_img_path.exists() {
- match std::fs::read(&ir_img_path) {
- Ok(image_data) => {
- println!("读取照片成功");
- let image_data = base64::encode(&image_data);
- let base64_string = String::from("data:image/jpg;base64,");
- std::fs::remove_file(ir_img_path).unwrap();
- result.img_base64.insert("0".to_string(), base64_string + &image_data);
- }
- Err(e) => {
- println!("读取照片抛异常");
- println!(
- "{:?} {:?}",
- e,
- "ir.jpg",
- );
- }
- };
- }
- }
- if colorResult==0{
- if color_img_path.exists() {
- match std::fs::read(&color_img_path) {
- Ok(image_data) => {
- println!("读取照片成功");
- let image_data = base64::encode(&image_data);
- let base64_string = String::from("data:image/jpg;base64,");
- std::fs::remove_file(color_img_path).unwrap();
- result.img_base64.insert("1".to_string(), base64_string + &image_data);
- }
- Err(e) => {
- println!("读取照片抛异常");
- println!(
- "{:?} {:?}",
- e,
- "color.jpg",
- );
- }
- };
- }
- }
- let mut ocritem = RecogIDCardEXResultObject::default();
- let mut index: c_int = 0;
- //orc识别文字
- let mut mrztext = [0; 1024];
- let x = unsafe {V7_VIS_GETMRZTEXT.get_unchecked()(mrztext.as_mut_ptr())};
- if x==0{
- let result_item = ["MRZ".to_string(), decode(&mrztext)];
- ocritem.mrz_result.insert(index, result_item);
- index+=1;
- }
- let mut data:[u16; 256] = [0; 256];
- let mut len = unsafe {V7_RDO_getBytesByIndex.get_unchecked()(0,data.as_mut_ptr())};
- if len>0{
- ocritem.mrz_result.insert(index, ["编号".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_RDO_getBytesByIndex.get_unchecked()(1,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["国籍".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_RDO_getBytesByIndex.get_unchecked()(2,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["民族".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_RDO_getBytesByIndex.get_unchecked()(3,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["姓名".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_RDO_getBytesByIndex.get_unchecked()(4,data.as_mut_ptr())};
- let cardType= unsafe {V7_GET_CARDTYPE.get_unchecked()()};
- if cardType==101{
- //身份证是UTF8格式
- ocritem.mrz_result.insert(index, ["中文名".to_string(), decode(&data)]);
- }else{
- ocritem.mrz_result.insert(index, ["中文名".to_string(), decode(&data)]);
- // //中国护照的中文姓名 是GBK编码的
- // let name=GB18030.decode(&data, DecoderTrap::Strict).unwrap();
- // ocritem.mrz_result.insert(index, ["中文名".to_string(), name.replace("\u{0}","")]);
- }
- index+=1;
- len = unsafe {V7_RDO_getBytesByIndex.get_unchecked()(5,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["性别".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_RDO_getBytesByIndex.get_unchecked()(6,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["出生日期".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_RDO_getBytesByIndex.get_unchecked()(7,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["地址".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_RDO_getBytesByIndex.get_unchecked()(8,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["签发机关".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_RDO_getBytesByIndex.get_unchecked()(9,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["有效期始".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_RDO_getBytesByIndex.get_unchecked()(10,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["有效期止".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_RDO_getBytesByIndex.get_unchecked()(20,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["港澳台ID".to_string(), decode(&data)]);
- index+=1;
- }
- else{
- len = unsafe {V7_VIS_getBytesByIndex.get_unchecked()(0,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["编号".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_VIS_getBytesByIndex.get_unchecked()(1,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["国籍".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_VIS_getBytesByIndex.get_unchecked()(2,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["民族".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_VIS_getBytesByIndex.get_unchecked()(3,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["姓名".to_string(), decode(&data)]);
- index+=1;
-
- //中国护照的中文姓名 是GBK编码的, 身份证不会执行到这里
- len = unsafe {V7_VIS_getBytesByIndex.get_unchecked()(4,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["中文名".to_string(), decode(&data)]);
- // let name=GB18030.decode(&data, DecoderTrap::Strict).unwrap();
- // ocritem.mrz_result.insert(index, ["中文名".to_string(), name.replace("\u{0}","")]);
- index+=1;
- len = unsafe {V7_VIS_getBytesByIndex.get_unchecked()(5,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["性别".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_VIS_getBytesByIndex.get_unchecked()(6,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["出生日期".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_VIS_getBytesByIndex.get_unchecked()(7,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["地址".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_VIS_getBytesByIndex.get_unchecked()(8,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["签发机关".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_VIS_getBytesByIndex.get_unchecked()(9,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["有效期始".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_VIS_getBytesByIndex.get_unchecked()(10,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["有效期止".to_string(), decode(&data)]);
- index+=1;
- len = unsafe {V7_VIS_getBytesByIndex.get_unchecked()(20,data.as_mut_ptr())};
- ocritem.mrz_result.insert(index, ["港澳台ID".to_string(), decode(&data)]);
- index+=1;
- }
-
- result.reg_info=ocritem;
- result.success = true;
- result.card_type = unsafe {V7_GET_CARDTYPE.get_unchecked()()};
- let elapsed = time_now.elapsed();
- println!("{:.6?}", elapsed);
- return result;
- }
- pub fn regcord_by_node(mut cx: FunctionContext) -> JsResult<JsNull> {
- println!("regcord_by_node");
- unsafe {
- NEED_RECORD.take();
- NEED_RECORD.set(true).unwrap();
- };
- Ok(cx.null())
- }
- #[neon::main]
- fn main(mut cx: ModuleContext) -> NeonResult<()> {
- cx.export_function("init", init_by_node)?;
- cx.export_function("start", start)?;
- cx.export_function("regcord_by_node", regcord_by_node)?;
- Ok(())
- }
到此这篇关于使用rust调用c++静态库并编译nodejs包的文章就介绍到这了,更多相关rust调用c++静态库内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!