A call to PInvoke function '[...]' has unbalanced the stack
Maybe the problem lies in the calling convention. Are you sure the unmanaged function was compiled as stdcall and not something else ( i would guess fastcall ) ?
A call to PInvoke function has unbalanced the stack
The only clear error in HttpFetchW
that I can see is that C# ulong
is 64 bits wide, by C++ ULONG
is 32 bits wide. The C# code for the final parameter should be uint
.
Other things to check include the calling convention. Are you sure it is cdecl
? Are you sure that SetLastError
should be true
?
As for the callback, you make the same error with ulong
. And the abort
parameter is LPBOOL
. That is a pointer to BOOL
. So you should declare the C# parameter as a ref
parameter. And the callback is declared with CALLBACK
which is stdcall
.
So the delegate should be:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate void dlgDownloadingCB(
uint elapsedSec,
IntPtr lParam,
ref bool abort
);
Or simply delete the UnmanagedFunctionPointer
attribute since the default is stdcall
.
I think it exceptionally likely that since the callback is stdcall
, so will the function. I expect that the FETCH_API
macro expands to both the return enum and the calling convention. Since you did not supply those details, I can only guess. You'll need to check.
The other thing that we cannot check is CB_DOWNLOADING
.
Anyway, with those assumptions, the function becomes:
[DllImport(dllPath, CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern FETCH HttpFetchW(
string url,
out System.Runtime.InteropServices.ComTypes.IStream retval,
string usrname,
string pwd,
bool unzip,
dlgDownloadingCB cb,
IntPtr cb_param,
string ctype,
uint ctypelen
);
A call to PInvoke function ... has unbalanced the stack
Two mistakes:
- The calling convention should be
Stdcall
. - The parameter types are all wrong. The first four parameters are
uint
and the final parameter isUIntPtr
.
You need to take care when reading the documentation. It can be found here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms646260.aspx
A call to PInvoke function has unbalanced the stack. This is likely because the managed PInvoke .. (.NET 4)
Add this along with dll import.
, CallingConvention = CallingConvention.Cdecl)]
As taken from here.
Platform invoke
To improve performance in interoperability with
unmanaged code, incorrect calling conventions in a platform invoke now
cause the application to fail. In previous versions, the marshaling
layer resolved these errors up the stack.Debugging your applications
in Microsoft Visual Studio 2010 will alert you to these errors so you
can correct them. If you have binaries that cannot be updated, you can
include the element in your
application's configuration file to enable calling errors to be
resolved up the stack as in earlier versions. However, this may affect
the performance of your application.
Calling a C++ function from C# - unbalanced stack
IIRC, you need to decorate the delegate signature with a calling convention. Unfortunately, this can only be done via IL or generating the stub with Reflection.Emit.
You can try this:
protected static Type MakeDelegateType(Type returntype, List<Type> paramtypes)
{
ModuleBuilder dynamicMod = ... ; // supply this
TypeBuilder tb = dynamicMod.DefineType("delegate-maker" + Guid.NewGuid(),
TypeAttributes.Public | TypeAttributes.Sealed, typeof(MulticastDelegate));
tb.DefineConstructor(MethodAttributes.RTSpecialName |
MethodAttributes.SpecialName | MethodAttributes.Public |
MethodAttributes.HideBySig, CallingConventions.Standard,
new Type[] { typeof(object), typeof(IntPtr) }).
SetImplementationFlags(MethodImplAttributes.Runtime);
var inv = tb.DefineMethod("Invoke", MethodAttributes.Public |
MethodAttributes.Virtual | MethodAttributes.NewSlot |
MethodAttributes.HideBySig,
CallingConventions.Standard ,returntype,null,
new Type[]
{
// this is the important bit
typeof(System.Runtime.CompilerServices.CallConvCdecl)
},
paramtypes.ToArray(), null, null);
inv.SetImplementationFlags(MethodImplAttributes.Runtime);
var t = tb.CreateType();
return t;
}
.Rdlc Report in MVC project - Managed Debugging Assistant 'PInvokeStackImbalance'
According to this answer, PInvokeStackImbalance is more of a "debugging assistant" than an exception. So...
In my case, as it did not prevent the report from being rendered, I just disabled this exception when debugging my project (see Tell the debugger to continue on user-unhandled exceptions). This did the trick for me.
A call to PInvoke function [function name] has unbalanced the stack
There is a mismatch in calling conventions, which causes the stack unbalance.
Since runCommand
is a member function of MyClass
, the calling convention used for it is not __cdecl
, but __thiscall
(note that there is an implicit "this
" pointer passed as argument with non-static member functions of C++ classes).
You may want to either export a pure C interface function (not a C++ class member function) from your DLL for P/Invoke'ing, or you can use C++/CLI to build a tiny bridging layer between native and managed code, wrapping your C++ native class in a .NET managed class written in C++/CLI, and use that managed class wrapper from C#.
Related Topics
How to Remove Whitespace on Merge
How to Edit CSS Style of a Div Using C# in .Net
Handle Modelstate Validation in ASP.NET Web API
How to Get Variable Name Using Reflection
How to Read ASP.NET Core Response.Body
Getting Path Relative to the Current Working Directory
Routing in ASP.NET MVC, Showing Username in Url
Sending Arguments to Background Worker
A Method to Count Occurrences in a List
SQL Command Insert Is Working But the Data Not Appear in Table
Adding Stylesheets Programmatically in ASP.NET
What's the Difference Between System.Valuetuple and System.Tuple
Recursively Get Properties & Child Properties of a Class
Why Use Icollection and Not Ienumerable or List<T> on Many-Many/One-Many Relationships
Difference Between Forward Slash (/) and Backslash (\) in File Path
Inheritance from Multiple Interfaces with the Same Method Name