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;
}

Начиная мы регистрируем один обработчик Ibox_Controller_SetSendReaderRequestActio, и другие функции будут использовать этот обработчик, но проблема в том, что я не могу получить результат после обратного вызова.

Код 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?

1 ответ

Проверьте ваше определение ffi для Ibox_Controller_ReaderInfo. я думаю это

"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, что ваша функция возвращает указатель.

Другие вопросы по тегам