node-ffi Как преобразовать результат в нужную структуру после обратного вызова? - PullRequest
0 голосов
/ 15 января 2019

Пытаясь получить данные после обратного вызова, их нет, также желательно преобразовать данные в нужную вам структуру, как это сделать?

код 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 Ответ

0 голосов
/ 17 января 2019

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

"Ibox_Controller_ReaderInfo" : ['void', []]

должно больше нравиться:

"Ibox_Controller_ReaderInfo" : ['void*', []]

или даже

"Ibox_Controller_ReaderInfo" : ['pointer', []]

так как вы возвращаете указатель с Ibox_Controller_ReaderInfo()

EDIT: Подумав немного об этом, вам может понадобиться что-то вроде этого:

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

...