使用node-ffi调用dll(主要解决unsigned char*作为返回值时遇到的问题)

  关于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;//返回排好序的新对象
}

你可能感兴趣的:(node-ffi,dll,js,c++,nodejs,dll,指针)