I have made a very simple Dll like this:
extern "C"
{
__declspec(dllexport) int Try(int v)
{
return 10 + v;
}
}
Then I want to use it in my C# app:
class Program
{
[DllImport("TestLib.dll")]
public static extern int Try(int v);
static void Main(string[] args)
{
Console.WriteLine("Wynik: " + Try(20));
Console.ReadLine();
}
}
It was working until I have tried to pas parameter. Now I have following error at runtime:
A call to PInvoke function 'ConsoleApplication2!ConsoleApplication1.Program::Try' 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.
I have no idea where is the problem.
The error message you've got contains a good advice indeed:
You should have the same calling convention specified on both sides (C++ dll and C# assembly). In C++ you can specify it by prepending function declaration with one of __cdecl, __stdcall, etc.
On the C# side you specify it with DllImport attribute, the default one is CallingConvention.StdCall which corresponds to __stdcall in C++, so, it looks like you have a __cdecl on the C++ side. To fix the issue either use __stdcall in your DLL as shown above, or use CDecl in C# like this:
The default calling convention in C and C++ is
__cdecl
; the default calling convention used by .NET P/Invoke is__stdcall
-- you need to reconcile these two.Either make your native function
__stdcall
, as Hans suggested:Or make your managed P/Invoke signature use
__cdecl
: