2

I am tasked with interfacing a C# program to a .DLL with unmanaged code. I can't find anything on the internet to help me get this to work. I get a PInvokeStackImbalance exception. I have tried changing the CallingConvention to .Winapi with no luck. I may be going about this completely wrong so any guidance on how to approach this is appreciated!

Here is the unmanaged code I must work with:

extern "C" __declspec(dllexport) int WINAPI GetAlarm (unsigned short hndl, ALARMALL *alarm);

typedef struct {
    ALARM alarm [ALMMAX];
} ALARMALL;
ALMMAX = 24

typedef struct {
    short eno;
    unsigned char sts;
    char msg[32];
} ZALARM;

Here is the managed C# side that I've written:

[DllImport("my.dll", EntryPoint = "GetAlarm", CallingConvention = CallingConvention.Cdecl)]
public static extern int GetAlarm(ushort hndl, ALARMALL alarm);

public struct ALARMALL 
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
    ZALARM alarm;
}

[StructLayout(LayoutKind.Sequential)]
public struct ZALARM
{
    [MarshalAs(UnmanagedType.I2)]
    public short eno;

    [MarshalAs(UnmanagedType.U1)]
    public byte sts;

    [MarshalAs(UnmanagedType.I1, SizeConst = 32)]
    public char msg;
}
oso0690
  • 69
  • 7
  • 1
    It's not cdecl. Why would you do that? WINAPI expands to stdcall. The function accepts a pointer to struct. You pass it by value. Pass it by ref or out depending on semantics. You won't have much luck reading anything out of msg either. – David Heffernan Mar 22 '18 at 21:07
  • [Exporting functions from a DLL with dllexport](https://stackoverflow.com/questions/538134/exporting-functions-from-a-dll-with-dllexport) – Jimi Mar 22 '18 at 21:07

1 Answers1

2

Finally got this working correctly so I'll post for anybody that might find it useful.

[DllImport("my.dll", EntryPoint = "GetAlarm")]
public static extern int GetAlarm(ushort hndl, ref ALARMALL alarm);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct ALARMALL
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
    public ZALARM[] alarm;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct ZALARM
{
    public short eno;

    public byte sts;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string msg;
oso0690
  • 69
  • 7