exomic exomic - 15 days ago 7
C# Question

Equivalent of C++ typedef struct to C#

I'm working on a project that need to communicate to a DLL. The SDK provided have a demo project in C++ and it retreive the data from the DLL using the above typedef struct and it's working well but I have to do the same thing but in C# and I tried to create a similar struct but when i call the DLL my struct is filled in a different order.

typedef struct tagTrackIRData
{
unsigned short wNPStatus;
unsigned short wPFrameSignature;
unsigned long dwNPIOData;

float fNPRoll;
float fNPPitch;
float fNPYaw;
float fNPX;
float fNPY;
float fNPZ;
float fNPRawX;
float fNPRawY;
float fNPRawZ;
float fNPDeltaX;
float fNPDeltaY;
float fNPDeltaZ;
float fNPSmoothX;
float fNPSmoothY;
float fNPSmoothZ;
} TRACKIRDATA, *LPTRACKIRDATA;


The problem is that I received in C# the struct above but I'm not able to assign it in the same struct format in C# (The struct is from a c++ dll and my program calling it is in C#). I tried to use this kind of converted struct in C# but the data is not going into the right variable name probably due to the missing *LPTRACKIRDATA.

struct TRACKIRDATA
{
public ushort wNPStatus;
public ushort wPFrameSignature;
public ulong dwNPIOData;

public float fNPRoll;
public float fNPPitch;
public float fNPYaw;
public float fNPX;
public float fNPY;
public float fNPZ;
public float fNPRawX;
public float fNPRawY;
public float fNPRawZ;
public float fNPDeltaX;
public float fNPDeltaY;
public float fNPDeltaZ;
public float fNPSmoothX;
public float fNPSmoothY;
public float fNPSmoothZ;
}


I'm calling the DLL in C# using this code:

TRACKIRDATA tid;
NPRESULT gdRes = getData(&tid);


Where getData() is

private delegate NPRESULT NP_GetData(TRACKIRDATA* data);
getData = (NP_GetData)Marshal.GetDelegateForFunctionPointer(procAddrNP_GetData, typeof(NP_GetData));


Thanks @Asik you were right! The problem was caused by the wrong type equivalent of dwNPIOData because the usigned long in C++ is 32Bits and in C# it's a 64bits size. The solution was to use the type uint32 in C#
public uint dwNPIOData;

Answer

Keep in mind integer types do not mean the same things in C++ and C#. In particular, long means at least 32 bits in C++, but it means strictly 64 bits in C#*. Alignment could also differ since you don't specify it explicitly in either language.

In short, you'll need to use equivalent types and ensure alignment is exactly the same for the mapping to work. It has nothing to do with the "missing *LPTRACKIRDATA".

*The question originally had C# ulong in place of uint.