node-ffi-napi not receiving any response from dll on method call, possible struct issue?

652 views Asked by At

So C++ isn't my strong suit so it's very likely I've made a mistake here in the creation of my struct types, I don't quite understand how to create the equivalent return type the C++ code expects on the js side.

Here's a working example from the 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);

    }

Here is the IO_SpecificData type:

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;

And the IO_SArgBlockParam type:

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;

I did not write the C++ so I'm not sure why it's done the way it is.

Here's what I did on the js side, (one of the many, many versions I've tried). I created two equivalents of the struct types defined above like so:

    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
    }),

You might notice that I'm missing the *pu8ArgBlock from IO_SArgBlockParam. That's because I'm now trying to build the struct incrementally in the method call as seen below.

First here's where I set up the dll and methods:

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

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

And here is the method call itself:

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

I don't get any errors when it runs, it just never seems to get out of the method call. I've tried a couple different options, I don't see anything glaringly wrong with what I've done. The connect function works but as soon as anything requires that IO_SArgBlockParam return type it just doesn't work. I'm obviously making a mistake. If anyone has any idea how to solve this I'd be very grateful.

EDIT: Forgot to mention, this is running on an Electron child process. When it's run on the main process it kills Electron and returns this 'Process finished with exit code -1073741819 (0xC0000005)'.

0

There are 0 answers