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

2 篇文章 0 订阅
2 篇文章 0 订阅

  关于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;//返回排好序的新对象
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
使用node-gyp和ffi-napi模块让Node.js与Python进行交互,可以按照以下步骤: 1. 确保你已经安装了Node.js和Python。 2. 安装node-gyp。你可以使用npm在终端中输入以下命令来安装: ``` npm install -g node-gyp ``` 3. 创建一个Node.js项目,并在项目文件夹下执行以下命令来创建一个binding.gyp文件: ``` node-gyp configure ``` 4. 编写一个C++的扩展模块,其中包含Python的头文件和函数调用。你可以将扩展模块文件命名为example.cc。 5. 在binding.gyp文件中添加一些内容,以便将C++扩展模块编译成Node.js模块。以下是一个binding.gyp文件的示例: ``` { "targets": [ { "target_name": "example", "sources": [ "example.cc" ], "include_dirs": [ "<!(python -c \"from distutils.sysconfig import get_python_inc; print(get_python_inc())\")" ], "libraries": [ "-lpython2.7" ], "cflags": [ "-Wall", "-fPIC", "-O3" ], "cflags_cc": [ "-Wall", "-fPIC", "-O3", "-std=c++11" ] } ] } ``` 6. 使用node-gyp编译并构建你的扩展模块。在项目文件夹下执行以下命令: ``` node-gyp build ``` 7. 在Node.js代码中使用ffi-napi模块来调用C++扩展模块,以便与Python交互。以下是一个Node.js代码的示例: ``` const ffi = require('ffi-napi'); const lib = ffi.Library('./build/Release/example', { 'multiply': [ 'int', [ 'int', 'int' ] ], 'add': [ 'int', [ 'int', 'int' ] ], 'subtract': [ 'int', [ 'int', 'int' ] ] }); console.log(lib.multiply(2, 3)); console.log(lib.add(2, 3)); console.log(lib.subtract(2, 3)); ``` 在这个示例中,我们使用了multiply、add和subtract这三个函数,它们都是在C++扩展模块中定义的。这个Node.js代码将打印出6、5和-1,它们分别是multiply、add和subtract函数的返回值。 以上就是使用node-gyp和ffi-napi模块让Node.js与Python进行交互的步骤。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值