关于node.js和C交互的方法

下面来至https://blog.csdn.net/cut001/article/details/69397022的方法
FUNCTION ulong DesEnCodeHex(string str, string key, ref string outstr) library “zm_2007.dll”

int DesEnCodeHex(const char* str,const char* key, char* outstr) ; //c 接口描述 字符指针传出

function long LIV_open(long vender,long index,ref long handle) library “living1.dll”

int LIV_open(int vender,int index, int* handle);////c 接口描述 整形指针传出。

function long LIV_get_hardware_info(long handle, ref LIV_hardware_info info) library “living1.dll”

int LIV_get_hardware_info(int handle,LIV_hardware_info info); //结构体指针传出

node.js调用动态库,采用node-ffi 模块。

var FFI = require(‘ffi’);
var ref = require(‘ref’);
var Struct = require(‘ref-struct’);
var refArray = require(‘ref-array’);
1、根据参数类型声明函数。
char* => string //也可以直接用 char *
int* => ref.refType(‘int’) //也可以直接用 int *
struct *=>ref.refType(liv_hardware_info)
struct[] *=> ref.refType(liv_hardware_info,3) //结构体数组
VOID * => ref.refType(‘pointer’)

结构体中的参数:
char* [] => refArray(‘byte’, 8)
基本类型
基本类型已经定义在了ref.types里,可以直接使用类型字符串或者’ref.types’中的类型对象。而对于枚举类型,简单当作int或者uint处理就可以了。

指针
对于指针类型,简单类型可以直接在参数列表里写int *,pointer这样的,生成类型的指针可以用ref.refType(type)。在调用函数时,执行var vRef = ref.alloc(type)得到一个引用对象,将对象传入函数即可。需要获取vRef指向的值v可以用var v = ref.deref(vRef)。对字符串类型的buffer可能需要使用ref.readCString(buffer)来读取(它可以处理末尾的’\0’)。

var intPtr = ref.refType(‘int’);
var liv_hardware_info = Struct({
‘developernumber’: ‘int’,
‘serialnumber’: refArray(‘byte’, 8),
‘manufacturedate’: ‘int’
});

let zm2007 = new FFI.Library(“./dll/zm_2007.dll”, {
‘DesEnCodeHex’: [‘int’, [‘string’, ‘string’, ‘string’]],
‘DesDeCodeHex’: [‘int’, [‘string’, ‘string’, ‘string’]],
‘LIV_open’: [‘int’, [‘int’, ‘int’, intPtr]],
‘LIV_get_hardware_info’: [‘int’, [‘int’, ref.refType(liv_hardware_info)]]
});
2、调用方法

var handleRef = ref.alloc(‘int’);//预先分配int 指针空间
let li_rtn = zm2007.LIV_open(0, 0, handleRef)
ll_handle = handleRef.deref();//获取int值

var lt = new Buffer(512).fill(" ");
zm2007.DesEnCodeHex(st, '770814', lt);
let ls_out = lt.toString("ascii"); //buffer中即为传出参数

var liv_info = new liv_hardware_info();//结构体初始化
zm2007.LIV_get_hardware_info(ll_handle, liv_info.ref());//调用
const buf = Buffer.from(liv_info.serialnumber); //获取已生成结构体中属性数据。

补充一点:字符集引起的中文乱码问题
默认node.js是utf8字符串,而我们的dll很多都是gbk编码,从参数的传入需要转成gbk
转码一般用这个模块,纯js版本
var iconv = require(‘iconv-lite’);

var infoRef = new Buffer(512);//调用函数预先分配空间
//开始调用。infoRef中是dll返回的gbk 数据串。

var as_data = iconv.decode(infoRef, ‘GBK’);//解码成utf8.

var userbuffer = iconv.encode(as_data, ‘gbk’);//utf8数据编码成gbk

总结: 中文 传入参数需要转码成gbk ,传出参数需要转码成utf8.

先记录,后面再加入内存直接映射的方法。

相关文章
相关标签/搜索