Managed Debugging Assistant 'PInvokeStackImbalance' has detected a... on trivial method
<p>I am calling a Delphi function from C# and get the error:</p>

<blockquote>
  <p>Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in ...</p>
</blockquote>

<p>I've exhausted attempts changing the .Net code to fit the Delphi signatures, why it doesn't work with basic Integers has me stumped, does anyone know where I am going wrong?</p>

<p>Even the simplest function using 2 integers produces the error. </p>

<p>I'm targeting x86 and have put in a couple of hours research but the following solutions haven't helped <a href="https://stackoverflow.com/questions/26040211/pinvokestackimbalance-when-calling-delphi-dll-function">here</a>,
<a href="https://stackoverflow.com/questions/3506796/pinvokestackimbalance-how-can-i-fix-this-or-turn-it-off">here</a> and <a href="https://stackoverflow.com/questions/2390407/pinvokestackimbalance-c-sharp-call-to-unmanaged-c-function">here</a> and this <a href="https://stackoverflow.com/questions/2951719/what-net-unmanagedtype-is-unicode-utf-16">one</a>. </p>

<p>This is the Delphi Code (compiled DLL version can be downloaded from <a href="http://tempsend.com/C1E8061686" rel="nofollow noreferrer">here</a>):</p>

<pre><code>unit PasBallEntry;
interface

procedure EntryPoint( InInt: integer; InStr: PChar;
                      var OutInt: integer; var OutStr: PChar); stdcall;

procedure ReleaseString( OutStr: PChar); stdcall;


procedure TimTamC( InInt: integer; InStr: PChar;
                   var OutInt: integer; var OutStr: PChar); cdecl;

procedure ReleaseStringC( OutStr: PChar); cdecl;

procedure TimTamCS( InInt: integer; InStr: PChar;
                    var OutInt: integer; var OutStr: PChar); cdecl; stdcall;

procedure ReleaseStringCS( OutStr: PChar); cdecl; stdcall;

procedure OneTwoS( var A, B: integer); stdcall;
procedure OneTwoC( var A, B: integer); cdecl;
procedure OneTwoCS( var A, B: integer); cdecl; stdcall;

exports
EntryPoint    name 'TimTam',
ReleaseString name 'ReleaseString';

implementation

uses Windows, SyncObjs, Classes, Generics.Collections;

var
  Gate: TCriticalSection;
  Strs: TStrings;
  StrP: TList&lt;PChar&gt;;

procedure EntryPoint( InInt: integer; InStr: PChar;
                      var OutInt: integer; var OutStr: PChar);
var
  InStrL, OutStrL: string;
begin
  OutInt  := 2 * InInt;
  InStrL  := InStr;
  OutStrL := InStrL + '_OUT!';
  UniqueString( OutStrL);
  if OutStrL = '' then
      OutStr := nil
    else
      begin
      OutStr := PChar( OutStrL);
      Gate.Enter;
      Strs.Add( OutStrL);
      StrP.Add( OutStr );
      Gate.Leave
      end
end;

procedure ReleaseString( OutStr: PChar);
var
  I: integer;
begin
  if not assigned( OutStr) then exit;
  Gate.Enter;
  StrP.Insert( I, OutStr);
  if I &gt;= 0 then
    begin
    StrP.Delete( I);
    Strs.Delete( I)
    end;
  Gate.Leave
end;

procedure TimTamC( InInt: integer; InStr: PChar;
                   var OutInt: integer; var OutStr: PChar);
begin
  EntryPoint( InInt, InStr, OutInt, OutStr)
end;

procedure ReleaseStringC( OutStr: PChar);
begin
  ReleaseString( OutStr)
end;

procedure TimTamCS( InInt: integer; InStr: PChar;
                    var OutInt: integer; var OutStr: PChar);
begin
  EntryPoint( InInt, InStr, OutInt, OutStr)
end;

procedure ReleaseStringCS( OutStr: PChar);
begin
  ReleaseString( OutStr)
end;

procedure OneTwoS( var A, B: integer);
begin
  A := 1;
  B := 2
end;

procedure OneTwoC( var A, B: integer);
begin
  A := 1;
  B := 2
end;

procedure OneTwoCS( var A, B: integer);
begin
  A := 1;
  B := 2
end;

initialization
  Gate := TCriticalSection.Create;
  Strs := TStringList.Create;
  StrP := TList&lt;PChar&gt;.Create

finalization
  Strs.Free;
  Gate.Free;
  StrP.Free

end.
</code></pre>

<p>Here is the .Net code:</p>

<pre><code>[DllImport("PascalBall.dll", EntryPoint = "TimTam", CallingConvention = CallingConvention.Cdecl)]
public static extern void OneTwoC(ref int a, ref int b);

[DllImport("PascalBall.dll", EntryPoint = "TimTam", CallingConvention = CallingConvention.StdCall)]
public static extern void OneTwoS(ref int a, ref int b);

[DllImport("PascalBall.dll", EntryPoint = "TimTam", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern void TimTamC(int inputInt, string inputString, ref int outputInt, ref string outputString);

private void button1_Click(object sender, EventArgs e)
{
    int a = 0;
    int b = 0;

    //Both these PInvoke calls fail (either StdCall or Cdecl)
    OneTwoS(ref a, ref b);

    OneTwoC(ref a, ref b);

    System.Diagnostics.Debug.WriteLine(a + b);
}

private void button2_Click(object sender, EventArgs e)
{
    int outInt = 1;
    string outStr = "world";
    const int stringBufferSize = 1024;
    var outputStringBuffer = new String('\x00', stringBufferSize);

    try
    {
        TimTamC(1, outputStringBuffer, ref outInt, ref outputStringBuffer);
        ReleaseString(ref outStr);
    }
    catch (Exception ex)
    {
    }
}
</code></pre>

<p><strong>Edit 1:</strong> I <em>think</em> I have the EntryPoint correct using TimTam, because I get a <strong>System.EntryPointNotFoundException</strong> if I try anything else, see here:</p>

<p><a href="https://i.stack.imgur.com/CWwhP.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/CWwhP.png" alt="enter image description here"></a></p>