node.js - node-ffi 回调后如何将结果转换为所需的结构?
问题描述
想在回调后获取数据,自己没有,还想把数据转换成你需要的结构怎么办呢?
C代码:
main.c
Ibox_Controller_SetSendReaderRequestAction(&sendReaderRequest);
Ibox_Result_ReaderInfo *readerInfoResult = Ibox_Controller_ReaderInfo();
hw.h
Ibox_Result_ReaderInfo *Ibox_Controller_ReaderInfo();
void Ibox_Controller_SetSendReaderRequestAction(IboxSendReaderRequestAction action);
Ibox_MemoryStruct *sendReaderRequest(char *request, int length);
typedef struct {
const char *errorMessage;
const char *bootloaderVersion;
const char *firmwareVersion;
const char *hardwareVersion;
int errorCode;
} Ibox_Result_ReaderInfo;
hw.c
char *sendData(char *buf, int size, uint16_t *retsize)
{
char *retbuf = 0;
....
return retbuf;
}
Ibox_MemoryStruct *sendReaderRequest(char *request, int length)
{
uint16_t responseLength = 0;
char *responseData = sendData(request, length, &responseLength);
Ibox_MemoryStruct *response = malloc(sizeof(Ibox_MemoryStruct));
response->length = responseLength;
response->data = responseData;
return response;
}
一开始我们注册了一个 handler Ibox_Controller_SetSendReaderRequestActio
,其他函数都会使用这个 handler ,但是问题是回调后我不能得到结果。
JS代码
var ffi = require('ffi');
var ref = require('ref');
var ArrayType = require('ref-array');
var StructType = require('ref-struct');
var lib = './libpay/libSDK.so';
var charPtrArray = ArrayType('char *', 64);
var charPtrArrayPtr = ref.refType(charPtrArray);
var voidPtr = ref.refType(ref.types.void);
var Ibox_Result_ReaderInfo = StructType({
errorMessage : string,
bootloaderVersion : string,
firmwareVersion : string,
hardwareVersion : string,
errorCode : string
});
var Ibox_MemoryStruct = StructType({
data : 'string',
length : ref.types.int
});
var sendReaderRequest = ffi.Callback('void', [charPtrArrayPtr, 'int'],
function(request, size) {
console.log(request, size);
return 'action\n1'; //result
});
var ib = ffi.Library(lib, {
"Ibox_Controller_SetSendReaderRequestAction" : ['void', ['pointer']],
"Ibox_Controller_ReaderInfo" : ['void', []],
});
ib.Ibox_Controller_SetSendReaderRequestAction(sendReaderRequest);
var resReaderInfo = ib.Ibox_Controller_ReaderInfo(); //result null why?
解决方案
检查 Ibox_Controller_ReaderInfo 的 ffi 定义。我认为这
"Ibox_Controller_ReaderInfo" : ['void', []]
应该更像:
"Ibox_Controller_ReaderInfo" : ['void*', []]
甚至
"Ibox_Controller_ReaderInfo" : ['pointer', []]
因为你正在返回一个指针Ibox_Controller_ReaderInfo()
编辑:多想一下,你可能需要一些类似的东西:
const Ibox_Result_ReaderInfo_Ptr = ref.refType(Ibox_Result_ReaderInfo);
var ib = ffi.Library(lib, {
"Ibox_Controller_SetSendReaderRequestAction" : ['void', ['pointer']],
"Ibox_Controller_ReaderInfo" : [Ibox_Result_ReaderInfo_Ptr, []],
});
因为你需要告诉 ffi 你的函数返回一个指针。
推荐阅读
- postfix-mta - 带有 Postfix、Dovecot 的本地邮件系统:MUA 在发送到别名地址时被错误的地址信息欺骗?
- python - 如何计算线性回归模型的训练误差和验证误差?
- c# - WebRequest 返回不可读的字符串
- android - 使用具有不同菜单的导航抽屉和底部导航栏时出现问题
- django - 在同一模型Django的另一个字段中传递一个字段的ID
- javascript - 如果用户没有空购物车,则不更改页面
- excel - 从 A 列的 366 天列表中查找/选择今天的日期
- scala - Scala set vs map in 理解
- python - 带有 db2 和 kerberos 的 sqlalchemy
- ggplot2 - 如何增加cor plot的红色圆圈内的文本大小?