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;
}
2
  • 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. Commented Mar 22, 2018 at 21:07
  • Exporting functions from a DLL with dllexport Commented Mar 22, 2018 at 21:07

1 Answer 1

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;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.