The following is a bit of C++ that is verified working:
typedef struct
{
PVOID buffer;
UINT32 length;
} DATA_BUFFER;
typedef struct
{
DATA_BUFFER TxBuf [1];
DATA_BUFFER RxBuf [1];
} JVM_COMM_BUFFER;
UINT32 SendAndRecv(
IN JHI_HANDLE handle,
IN CHAR* AppId,
INOUT JVM_COMM_BUFFER* pComm
);
The following is my attempt to port that to C#:
[StructLayout(LayoutKind.Sequential)]
public struct DATA_BUFFER
{
public byte[] buffer;
public uint length;
}
[StructLayout(LayoutKind.Sequential)]
public struct JVM_COMM_BUFFER
{
public DATA_BUFFER TxBuf;
public DATA_BUFFER RxBuf;
}
[DllImport("jhi.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
public static extern UInt32 SendAndRecv(IntPtr handle, string AppId, ref JVM_COMM_BUFFER pComm);
There is no exception thrown in the C# from marshalling, but the results are not the same for the C++ and C# versions. Any idea on what I’m missing?
The issue is the difference between just allocating memory and allocating a pinned object. Once I switched it to a pinned object, then the signature without any IntPtrs except the buffer field worked just fine.