electron中调用 ref-napi 做C语言类型转换,但默认为小端模式,如何修改模式呢?
与硬件通讯,单片机默认数据存储为大端模式,win系统默认为小端模式。
设置方式
ref.endianness = ‘BE’
var ref = require('ref-napi');
ref.endianness = 'BE'; //设为大端模式 即 字节B1,B2==》B1B2
ref.endianness = 'LE';//设为小端模式 即 字节B1,B2==》B2B1
如需要在部分场景下改用大端,则注意在处理数据前设为大端,处理完再恢复小端。
代码示例
var ref = require('ref-napi');
var StructType = require('ref-struct-napi');
let uint16 = ref.types.uint16;
let BDStructType = {
DATA1: uint16,
DATA2: uint16
};
//定义标定结构体
const BD_PARA_MSG_TYPE = StructType(BDStructType);
let myStruct = new BD_PARA_MSG_TYPE();
/*
将数组转化为结构体,并已指定模式解析
type 大小端模式 'BE'|'LE'
*/
function getStructByArray(arr, type) {
//解决大小端问题 硬件标定为大端模式
ref.endianness = type || 'LE';
//获得结构体的buffer实例 (也等于指针/地址)
let structRef = myStruct.ref();
Buffer.from(arr).copy(structRef);
let obj = JSON.parse(JSON.stringify(myStruct));
//恢复PC小端模式
ref.endianness = 'LE';
return obj;
}
console.log(getStructByArray([0, 1, 0, 2], 'BE'));
console.log(getStructByArray([0, 1, 0, 2], 'LE'));
//{ DATA1: 1, DATA2: 2 }
//{ DATA1: 256, DATA2: 512 }
运行结果
简单解释
int16 占两个字节,
大端以 B1B2合并则为,0x0000,0x0002=>十进制表示为1和2。
小端以B2B1合并,则为0x0100,0x0200=>十进制表示为256和512
同理,ref-array-napi基于 ref-napi 实现,如想修改大小端模式怎么做?
…我实在没找到配置项,只能简单粗暴改源码。
修改 node_modules/ref-array-napi/lib/array.js
var _ref = require('ref-napi')
_ref.endianness = 'BE'; //在_ref下新增该行
其他坑
1、字节对齐问题:C语言中int16类型存在字节对齐问题,字节起始位要以偶数位开始。
举个例子:
let BDStructType = {
DATA1: uint8, //字节0
DATA2: uint16 //字节1、2
DATA3: uint8 //字节3
};
let data=[0,1,2,3,4]
大端模式期望结果
{
DATA1:0,
DATA2:0x0102.
DATA3:3
}
实际结果
{DATA1:0, DATA2:0x0203.DATA3:4}
实际结果 DATA2并没有按期望取字节1,而是跳过字节1取了字节2。这就是因为C语言字节对齐规则导致的。
所以 int16类型的起始位要定义在偶数字节上。
如有更好方案,欢迎留言指教。如有疑问也请留言。
辛苦码字,转载请注明出处。