node-ffi-napi не получает никакого ответа от dll на вызов метода, возможная проблема struct? - PullRequest
1 голос
/ 25 марта 2020

Так что C ++ не моя сильная сторона, так что, скорее всего, я допустил ошибку при создании своих структурных типов, я не совсем понимаю, как создать эквивалентный тип возврата, который код C ++ ожидает в js side.

Вот рабочий пример из C ++:

    IO_PVHandle pvHandle;
    IO_EErrorType eError;
    IO_SArgBlockParam suArgBlock;

    pvHandle = connect("COM7");

    if (pvHandle == NULL)
    {
        return -1;
    }

    {
        INT8U au8Data[256];
        IO_SpecificData *psuSpecData = (IO_SpecificData *)au8Data;

        /* setup Argblock */
        suArgBlock.pu8ArgBlock = au8Data;
        suArgBlock.u16ArgBlockLength = 0;
        suArgBlock.u16ArgBlockLengthMax = sizeof(au8Data);

        eError = IO_eGetSpecificData(pvHandle, &suArgBlock);

    }

Вот тип IO_SpecificData:

typedef struct IO_SpecificData
{
    INT16U u16ArgBlockID; /**< \brief big endian, */
    INT16U u16VendorID; /**< \brief big endian */
    INT32U u32MasterID; /**< \brief big endian */
    INT8U u8MasterType;
    INT8U u8Features_1;
    INT8U u8Features_2;
    INT8U u8MaxMumberOfPorts;
    // PortTypes
}IO_SpecificData;

И тип IO_SArgBlockParam:

pu8ArgBlock points to the data. u16ArgBlockLength is used to tell the recipient the used length of the ArgBlock.
u16ArgBlockLengthMax defines the maximum length of the ArgBlock and can be bigger than u16ArgBlockLength, if a bigger answer is expected.
*/
typedef struct IO_SArgBlockParam
{
    INT8U *pu8ArgBlock; /**< \brief Data Buffer (Can be NULL if u16ArgBlockLengthMax = 0) */
    INT16U u16ArgBlockLength; /**< \brief Used length of pu8ArgBlock */
    INT16U u16ArgBlockLengthMax; /**< \brief Total Mem Length of pu8ArgBlock */
    INT16U u16ExpRefArgBlockId; /**< \brief Expected Response or referenced ArgBlock Id (0 = not used) */
}IO_SArgBlockParam;

Я не писал на C ++, поэтому я не уверен, почему он так и сделал.

Вот что я сделал на стороне js (один из многих, многих версии, которые я пробовал). Я создал два эквивалента типов структур, определенных выше, например, так:

    IO_SpecificData: StructType({
        'u16ArgBlockID': ref.types.uint16,
        'u16VendorID': ref.types.uint16,
        'u32MasterID': ref.types.uint32,
        'u8MasterType': ref.types.uint8,
        'u8Features_1': ref.types.uint8,
        'u8Features_2': ref.types.uint8,
        'u8MaxNumberOfPorts': ref.types.uint8
    }),
    IO_SArgBlockParam: StructType({
        'u16ArgBlockLength': ref.types.uint16,
        'u16ArgBlockLengthMax': ref.types.uint16,
        'u16ExpRefArgBlockId': ref.types.uint16
    }),

Вы можете заметить, что я пропускаю * pu8ArgBlock из IO_SArgBlockParam. Это потому, что я сейчас пытаюсь построить структуру постепенно в вызове метода, как показано ниже.

Сначала я установил dll и методы:

        let ArgBlockParam = ref.refType(DataStructure.IO_SArgBlockParam);

        this.DLL = ffi.Library(
            dllLocation,
            {
                /* USB interface management functions */
                'connect': [LONG, [STRING]],
                'IO_eGetSpecificData': [LONG, [LONG, ArgBlockParam]],
            });

И вот сам вызов метода:

    IO_eGetSpecificData(handle)
    {
        let struct = DataStructure.IOLM_SMI_SArgBlockParam;
        struct.defineProperty('pu8ArgBlock', ref.refType(DataStructure.IO_SpecificData));
        let argBlock = new struct({pu8ArgBlock: new Buffer(256), u16ArgBlockLength: 0,  u16ArgBlockLengthMax: 256, u16ExpRefArgBlockId: 0});
        console.log("calling", handle);
        let resultCode = this.DLL.IO_eGetSpecificData(handle, argBlock.ref());
        console.log("result code", resultCode);
        let result = new DLLFunctionsResultObject(resultCode);
        return result;
    }

Я не получаю никаких ошибок при запуске, просто кажется, что он никогда не выходит из вызова метода. Я пробовал пару разных вариантов, я не вижу ничего плохого в том, что я сделал. Функция подключения работает, но как только что-то требует возвращаемого типа IO_SArgBlockParam, он просто не работает Я явно ошибаюсь. Если у кого-то есть идеи, как решить эту проблему, я был бы очень признателен.

РЕДАКТИРОВАТЬ: Забыл упомянуть, это работает на дочернем процессе Electron. Когда он запускается в основном процессе, он убивает Электрон и возвращает этот «Процесс завершен с кодом выхода -1073741819 (0xC0000005)».

...