首页 > 解决方案 > 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?

标签: node.jsffinode-ffi

解决方案


检查 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 你的函数返回一个指针。


推荐阅读