关于nodeffi调用dll,网上千篇一律都是int和strng的传值返回,无符号字符指针作为返回值的情况少之又少,故在此记录一下自己这一周摸索出来的经验
普通类型的调用可以参考以下文章
ref官方文档
进乎技矣大佬的博客
先直接贴结果 用无符号字符指针接收只能接第一个字节,所以需要结合ref-array来构建指定长度的无符号字符数组,参数为无符号字符数组的指针
由于c指针传到js会被自动解引用所以也可以在数组中放入无符号字符指针,但是无符号字符指针的长度默认为8,所以数组长度需要除以8
代码如下
C++代码
TESTDLL_API unsigned char* test(
unsigned char* ubuffer, int bufLength, char* buffer, int bufferLength);
js代码
const ref = require('ref')
const refArray = require('ref-array')
const ffi = remote.require("ffi");
//构建长度为10的无符号字符数组
const sk = refArray('uchar' ,16);
//ucharPtr为uchar* 由于c指针传到js会被自动解引用所以也可以传入指针
//var ucharPtr = ref.refType('uchar');
//由于解引用的uchar*长度默认为8字节 所以数组长度为所需长度/8
//const sk = refArray(ucharPtr ,2);
//返回值类型为长度为2的无符号字符指针数组的指针
const DLL = ffi.Library('dll/Dll1.dll', {
'test': [ref.refType(sk), ['uchar*', 'int','string', 'int'], ],
});
由于js是弱类型语言,所以在接收返回值时不用专门开辟内存空间,可以直接接收返回值
/-------------------------------------------我是分割线--------------------------------------------------------------/
整体讲完了,就讲一下排坑过程吧
1. js返回值类型是uchar*时nodejs只能接收长度为1的buffer,值为返回值的首位无符号字符
c代码
TESTDLL_API unsigned char* test(
unsigned char* ubuffer, int bufLength, char* buffer, int bufferLength);
js代码
错误点:返回值直接定义为uchar*
const DLL = ffi.Library('dll/Dll1.dll', {
'test': 'uchar*', ['uchar*', 'int','string', 'int'], ],
});
原因分析:c++指针返回为js buffer会自动解引用所以无符号字符指针自动被解引用为无符号字符,所以就只有首位(未证实)
2. js返回值类型是ref.refType(“uchar*”)时nodejs只能接收到返回值的前8个字节
c代码
TESTDLL_API unsigned char* test(
unsigned char* ubuffer, int bufLength, char* buffer, int bufferLength);
js代码
错误点:返回值直接定义为uchar*
const DLL = ffi.Library('dll/Dll1.dll', {
'test': ref.refType("uchar*"), ['uchar*', 'int','string', 'int'], ],
});
原因分析:c++指针返回为js buffer会自动解引用,uchar**解引用为uchar*,ref模块中unchar*转换为buffer长度默认是8.(未证实)
小记录
Java FastJson转换后的json字符串,属性是按照首字母顺序排序的,所以如果js中使用JSON.stringfy()获得的字符串想要使用Java FastJson转换,就必须先对js对象属性进行排序,排序函数如下 :
function objKeySort(obj) {//排序的函数
var newkey = Object.keys(obj).sort();
//先用Object内置类的keys方法获取要排序对象的属性名,再利用Array原型上的sort方法对获取的属性名进行排序,newkey是一个数组
var newObj = {};//创建一个新的对象,用于存放排好序的键值对
for (var i = 0; i < newkey.length; i++) {//遍历newkey数组
newObj[newkey[i]] = obj[newkey[i]];//向新创建的对象中按照排好的顺序依次增加键值对
}
return newObj;//返回排好序的新对象
}