1

I am calling functions from a unmanaged dll in C#. And one of my calls to this dll is working. But the other one has more advanced Parameters and when I execute the Funkction in my C# Code:

[DllImport("IOLUSBIF20.dll", CallingConvention = CallingConvention.StdCall)]
public static extern long IOL_SetTransparentModeExt(long Handle, UInt32 Port, ref TTransparentParameters pTransparentParameters);

I get the following Error:

"PInvokeStackImbalance" : "A call to PInvoke function 'IO-Link Device Interface!IO_Link_Device_Interface.IOLUSBIF20Wrapper::IOL_SetTransparentModeExt' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature."

In the Header the signature of the function (and the struct) is defined as follows:

LONG __stdcall IOL_SetTransparentModeExt(LONG Handle, DWORD Port, TTransparentParameters * pTransparentParameters);


typedef struct TTransparentParametersStruct
{
  BYTE StartPattern[16];    /**< starting pattern */
  BYTE ReturnPattern[32];   /**< returning pattern */
} TTransparentParameters;

The struct that I pass as an Argument Looks as follows:

[StructLayout(LayoutKind.Sequential)]
    public struct TTransparentParameters
    {
        public Byte[] StartPattern;    /**< starting pattern */
        public Byte[] ReturnPattern;   /**< returning pattern */
    }
JZ997
  • 21
  • 3

1 Answers1

2

Your stack is not balanced, because the unmanaged data structure is composed by

BYTE StartPattern[16];    /**< starting pattern */
BYTE ReturnPattern[32];   /**< returning pattern */

which occupy 48 bytes, while your managed interpretation of those fields are of the wrong size. If you specify the size to the marshaler, your stack should be balanced:

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public Byte[] StartPattern;    /**< starting pattern */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public Byte[] ReturnPattern;   /**< returning pattern */
Yennefer
  • 5,704
  • 7
  • 31
  • 44
  • Hi and thanks for the quick answer! I also had to switch "long handle" to "uint handle" in my method parameters. I guess because long in c is a 32 bit data type and in c# it´s 64bit – JZ997 Feb 14 '19 at 07:49
  • Yes, I no longer see part of your answer, but keep in mind that your assembly should be compiled with the correct endianess as you might have different pinvoke signatures for 32 and 62 bits. Reagrding the size of a longs, have a look at this [answer](https://stackoverflow.com/questions/7607502/sizeoflong-in-64-bit-c) which might be helpful. – Yennefer Feb 14 '19 at 09:40