oso0690
oso0690

Reputation: 69

C# - How to marshal an unmanaged struct within a struct that contains arrays

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;
}

Upvotes: 2

Views: 1413

Answers (1)

oso0690
oso0690

Reputation: 69

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;

Upvotes: 2

Related Questions