22

I'm creating a very simple PInvoke sample:

extern "C" __declspec(dllexport) int Add(int a, int b)
{
    return a + b;
}

[DllImport("CommonNativeLib.dll")]
extern public static int Add(int a, int b);

return NativeMethods.Add(a, b);

But whenever I call the above NativeMethods.Add method I get the following managed debug assistant:

PInvokeStackImbalance was detected Message: A call to PInvoke function 'CommonManagedLib!CommonManagedLib.NativeMethods::Add' 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.

The call then completes with the expected return value, but having the MDA message appear is both annoying and worrying - I don't fully understand PInvoke yet, but from what I've read I'm pretty sure that my signature is correct - what am I doing wrong?

This is all on a 32-bit OS.

Justin
  • 84,773
  • 49
  • 224
  • 367

2 Answers2

42

You need to instead use either

[DllImport("CommonNativeLib.dll", CallingConvention = CallingConvention.Cdecl)]

or

extern "C" __declspec(dllexport) int __stdcall Add(int a, int b) ...

because regular C functions work differently than the Windows API functions; their "calling conventions" are different, meaning how they pass around parameters is different. (This was hinted at in the error.)

user541686
  • 205,094
  • 128
  • 528
  • 886
  • 3
    Actually the difference between Cdecl and StdCall is that with StdCall the callee is responsibe for clearing up the stack while in Cdecl the caller is. So when you call a function which expects Cdecl as StdCall your stack won't be cleaned up and therefor the warning. – ChrisWue Apr 09 '11 at 03:19
  • @ChrisWue: I was doing a hand-wavy explanation instead of going into the details, but yeah, that's the big difference; thanks. (And btw, that's StdCall, not StdDecl.) – user541686 Apr 09 '11 at 03:20
  • This solved the problem for me on both 32-bit and 64-bit OS even though the OP had 32-bits only. Thanks! – Ed Bayiates Sep 20 '12 at 20:28
1

The Stack Imbalance reasons are either the signature is not matching else Calling Convention by default calling convention is stdcall. When your calling convention is stdcall callee cleans the stack if you want caller to clean the stack us cdecl calling convention. you can find more Here

But if you are facing because of signature, just go through above link Solve Signature based Stack Imbalance issues using PInvoke extension

Community
  • 1
  • 1
Vijay Kumbhoje
  • 1,401
  • 2
  • 25
  • 44