Home > Software design >  C# DllImport - Call a function that returns an struct
C# DllImport - Call a function that returns an struct

Time:02-03

I am working in C# and I need to call a function in a C dll library. This function returns a struct but I can´t get anything.

This is the function I need to call and the struct that returns in C library:

ATHENA_API _DEVICE_INFO* __stdcall  GetDeviceInfoKeepConnection(_DEVICE_INFO* pDeviceInfo);

typedef struct TD_DEVICE_INFO{
   TCHAR  chDeviceName[256];
   int   nCommPort;
   int   nECGPos;
   int   nNumberOfChannel;
   int   nESUType;
   int   nTymestampType;
   int   nDeviceHandle;
   TCHAR  chDeviceID[260];
}_DEVICE_INFO;

This is my C# code trying to call the function:

[DllImport(@"\BAlertSDK\ABM_Athena.dll")]
static extern _DEVICE_INFO GetDeviceInfoKeepConnection(_DEVICE_INFO deviceInfo);

[StructLayout(LayoutKind.Sequential)]
struct _DEVICE_INFO
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string chDeviceName;
    public int nCommPort;
    public int nECGPos;
    public int nNumberOfChannel;
    public int nESUType;
    public int nTymestampType;
    public int nDeviceHandle;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string chDeviceID;
}

void Test_Click()
{
    _DEVICE_INFO d = new _DEVICE_INFO();
    _DEVICE_INFO deviceInfo = GetDeviceInfoKeepConnection(d);
}

The only I can get is an empty _DEVICE_INFO object. I think my problem is that I am not defining correctly the DEVICE INFO struct.

I have never worked with dll´s to this level. Can you help me?

Thanks in advance.

CodePudding user response:

Thanks to all!! The problem has solved with this:

Parameter pass by reference and struct charset Unicode.

Now, I have to call another function:

ATHENA_API int __stdcall GetEEGChannelsInfo( _EEGCHANNELS_INFO & stEEGChannelsInfo);

The "&" means that the parameter must by passed by reference too?

[DllImport(dll)] static extern int GetEEGChannelsInfo(ref _EEGCHANNELS_INFO e);

CodePudding user response:

It seems that the function GetDeviceInfoKeepConnection returns a pointer to _DEVICE_INFO struct. So, in your C# code, you need to change the definition of the function to:

[DllImport(@"\BAlertSDK\ABM_Athena.dll")] static extern IntPtr GetDeviceInfoKeepConnection(IntPtr deviceInfo);

And then you can access the struct data like this:

void Test_Click()
{
_DEVICE_INFO d = new _DEVICE_INFO();
IntPtr pDeviceInfo = Marshal.AllocHGlobal(Marshal.SizeOf(d));
Marshal.StructureToPtr(d, pDeviceInfo, false);
IntPtr deviceInfo = GetDeviceInfoKeepConnection(pDeviceInfo);
_DEVICE_INFO result = (_DEVICE_INFO)Marshal.PtrToStructure(deviceInfo, typeof(_DEVICE_INFO));
Marshal.FreeHGlobal(pDeviceInfo);
}

Note that, to ensure that the memory is cleaned up after use, you should use the Marshal.FreeHGlobal method to free the memory that was allocated by Marshal.AllocHGlobal.

  • Related