Search code examples
javajna

How to set up a correct size of buffer of the structure?


I have a documentation for DLL which I have to use where is defined a structure which is an argument to one of the native mathod.

It looks like here:

typedef struct
{
UNUM32 uiModuleState;
UNUM32 uiSerialNumber;
UNUM32 uiVCIIf;
UNUM32 uiModuleType;
CHAR8 szModuleName[256];
}
VTX_RT_VCI_ITEM;
typedef struct
{
UNUM32 uiNumVCIItems;
VTX_RT_VCI_ITEM * pVCIItems;
}
VTX_RT_VCI_ITEM_LIST;
Calling Convention:
SNUM32 VtxRtGetModuleIds( IO UNUM32* puiBufferLen,
IO VTX_RT_VCI_ITEM_LIST* pVCIItemList);

I have modeled that structure in the JNA like here

VTX_RT_VCI_ITEM

@Structure.FieldOrder({ "uiModuleState",
                        "uiSerialNumber",
                        "uiVCIIf",
                        "uiModuleType",
                        "szModuleName" })
public class VtxRtVciItem extends Structure
{
    public int uiModuleState;

    public int uiSerialNumber;

    public int uiVCIIf;

    public int uiModuleType;

    public char[] szModuleName = new char[VciRuntimeAPI.VTX_RT_SMALL_BUF_SIZE];

    public static class ByReference extends VtxRtVciItem implements Structure.ByReference {}

    public static class ByValue extends VtxRtVciItem implements Structure.ByValue {}

    public VtxRtVciItem()
    {
        super();
        read();
    }
}

VTX_RT_VCI_ITEM_LIST

@Structure.FieldOrder({ "uiNumVCIItems",
                        "pVCIItems" })
public class VtxRtVciItemList extends Structure
{
    public int uiNumVCIItems;

    public VtxRtVciItem.ByReference pVCIItems;

    public VtxRtVciItemList()
    {
        super();

    }
}

A first argument is described as follow puiBufferLen Size of the buffer pointed to by pVCIItemList.

How to set up a correct buffer size of that structure?

I was trying to do something like here but the size of that structure is 8 which means that VtxRtVciItem is not callculated.

VtxRtVciItemList vtxRtVciItemList = new VtxRtVciItemList();
IntByReference puiBufferLen = new IntByReference();
puiBufferLen.setValue(vtxRtVciItemList.size());

Solution

  • Your vtxRtVciItemList is just a structure with the number of list elements and a pointer to the actual list. The list buffer itself will be the size of each structure in the list (new VtxRtVciItem().size()) multiplied by the number of those elements (uiNumVCIItems).

    You don't show where you actually allocate that buffer, which you'll need to use the Structure.toArray() method to do.

    I think this is what you want to do, let me know if I've misinterpreted your request.

    int numItems = 42; // whatever your number of list items is
    VtxRtVciItem.ByReference[] vtxRtVciItemPointerArray = 
        (VtxRtVciItem.ByReference[]) new VtxRtVciItem.ByReference().toArray(numItems);
    VtxRtVciItemList vtxRtVciItemList = new VtxRtVciItemList();
    vtxRtVciItemList.uiNumVCIItems = numItems;
    vtxRtVciItemList.pVCIItems = vtxRtVciItemPointerArray[0];
    

    And then pass to your function:

    IntByReference puiBufferLen = 
        new IntByReference(vtxRtVciItemList.uiNumVCIItems * vtxRtVciItemPointerArray[0].size());
    VtxRtGetModuleIds(puiBufferLen, pVCIItemList);