Friday, July 19, 2013

Stack Imbalance on .NET P/Invoke

The stack imbalance warning when debugging .NET code which used P/Invoke to call DLL function is mostly caused  by wrong parameter calling convention. This post explains in more detail. The default parameter calling convention when using the dllimport attribute is stdcall calling convention, as you can see in this link: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.callingconvention(v=vs.100).aspx. This is the relevant excerpt:
The default value for the CallingConvention field is Winapi, which in turn defaults to StdCall convention.
This caused the stack handling becomes incorrect if you don't set the calling convention in your P/Invoke function declaration. Below is an example on how to do it right.
This is the DLL function declaration in C:
#ifdef __cplusplus
extern "C" {
#endif

__declspec(dllexport) void set_log_filename(char* log_file_path); 

#ifdef __cplusplus
}
#endif
and this is the P/Invoke function declaration in C#:
  DllImport("captcha_solver_dll.dll", CallingConvention = CallingConvention.Cdecl)]
  public static extern void set_log_filename(string log_file_path);
As you can see, I set the set_log_filename() function calling convention to "cdecl" in the C# code above. After this, there is no more stack imbalance warning during debugging.