I have been attempting to update to the latest HDF5DotNet wrappers (1.8.7) and am getting the following warnings (when running in DEBUG mode from VS2010):
PInvokeStackImbalance was detected
Message: A call to PInvoke function 'HDF5DotNet!::H5Fopen' 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 am using the pre-compiled binaries (HDF5DotNet assembly for .NET Framework 4.0 32-bit), but got the same result when I compiled from source.
Strangely, when executing my application that calls the HDF5DotNet wrappers in non-DEBUG mode, I see no problems. I did notice that between 1.8.6 and 1.8.7 all the calling conventions were switched from Cdecl to StdCall. Could this be causing this? I've seen other forums saying the CallingConvention should BE Cdecl...
Thanks!
Yes, calling a stdcall function as cdecl or the other way round causes a stack imbalance. The main difference between these conventions is that with cdecl the caller is responsible for removing the arguments from the stack, with stdcall the callee is responsible.
I guess in release mode you have the same bug. But you don't get the error because some runtime checks are disabled. A native program would crash in most cases where you use the wrong calling convention, but it seems like the .net interop code has a more robust stack handling that masks this problem.
Related
I have been using a pre-compiled DLL in some software for a few years now. Now that software required a new feature so I dusted off my project and made my changes. It was originally built for .NET 4.0, but since that is unsupported I switched to .NET 4.8, trying to keep the same major version to avoid too many differences.
My original code I did not specify a calling convention so I assume StdCall was used, but when I went to run it I got a "PInvoke has left the stack unbalanced" exception. I changed all call types to Cdecl, which resolved that error. I think this was correct to do, but it could be related to my problem still.
Now one particular method is called, (one that is supposed to give a human readable reason for an error code) the application closes. If I try to execute the method in the watch window I get an error that the target process exited with a seemingly random code (-1073740940) which does not seem like the intention of the DLL.
Since the DLL hasn't changed, I assume something about dllimport has that is causing this issue. The documentation for the DLL denotes a single long input and a char* return type which I assume means it is an ANSI string, but I've tried multiple return marshal types. This is what I think is the most correct DLLImport I've tried (the DLL I'm using is not public so I've changed the DLL name and entry point).:
[DllImport("provided.dll", EntryPoint = "getErrorString", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string GetDLLErrorString(long errorCode);
I have problem with release version of my application. After retarget windows store app to universal windows platform project i can't run application in release mode with Compile with .NET Native tool chain option checked.
I get an error:
Exception thrown: System.Reflection.MissingRuntimeArtifactException in System.Private.Reflection.Core.dll
Additional information: MakeGenericMethod() cannot create this generic method instantiation because the instantiation was not metadata-enabled: System.Linq.Enumerable.Distinct<System.Char>(System.Collections.Generic.IEnumerable<System.Char>)
For more information, please visit http://go.microsoft.com/fwlink/?LinkID=616868
When i disable Compile with .NET Native tool chain application is working and doesn't throw a exception.
Generally this is solution, but in Windows App Certification Kit i get failed result with errors (Test Supported API):
·API ExecuteAssembly in uwphost.dll is not supported for this application type. App.exe calls this API.
·API DllGetActivationFactory in uwphost.dll is not supported for this application type. App.exe has an export that forwards to this API.
·API OpenSemaphore in ap-ms-win-core-synch-11-1-0.dll is not supported for this application type. System.Threading.dll calls this API.
·API CreateSemaphore in api-ms-win-core-kernel32-legacy-11-1-0.dll is not supported for this application type. System.Threading.dll calls this API.
Someone can help?
The .NET Native runtime doesn't include a JIT compiler. As a result, all necessary native code must be generated in advance. A set of heuristics is used to determine what code should be generated, but these heuristics cannot cover all possible metaprogramming scenarios. Therefore, you must provide hints for these metaprogramming scenarios by using runtime directives. If the necessary metadata or implementation code is not available at runtime, your app throws a MissingMetadataException, MissingRuntimeArtifactException, or MissingInteropDataException exception. Two troubleshooters are available that will generate the appropriate entry for your runtime directives file that eliminates the exception:
The MissingMetadataException troubleshooter for types.
The MissingMetadataException troubleshooter for methods.
See here: https://msdn.microsoft.com/en-us/Library/dn600640%28v=vs.110%29.aspx
I'm getting this weird error on some stuff I've been using for quite a while. It may be a new thing in Visual Studio 2010 but I'm not sure.
I'm trying to call a unamanged function written in C++ from C#.
From what I've read on the internet and the error message itself it's got something to do with the fact that the signature in my C# file is not the same as the one from C++ but I really can't see it.
First of all this is my unamanged function below:
TEngine GCreateEngine(int width,int height,int depth,int deviceType);
And here is my function in C#:
[DllImport("Engine.dll", EntryPoint = "GCreateEngine", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr CreateEngine(int width,int height,int depth,int device);
When I debug into C++ I see all arguments just fine so thus I can only think it's got something to do with transforming from TEngine (which is a pointer to a class named CEngine) to IntPtr. I've used this before in VS2008 with no problem.
I had a _cdecl c++ dll that I called without any trouble from Visual Studio 2008, and then the identical code in Visual Studio 2010 would not work. I got the same PInvoke ... has unbalanced the stack error as well.
The solution for me was to specify the calling convention in the DllImport(...) attribute:
From:
[DllImport(CudaLibDir)]
To:
[DllImport(CudaLibDir, CallingConvention = CallingConvention.Cdecl)]
I guess they changed the default calling convention for DLLImport between .NET 3.5 and .NET 4.0?
It could also be that in the .NET Framework version 3.5, the pInvokeStackImbalance MDA is disabled by default. Under 4.0 (or maybe VS2010) it is enabled by default.
Yes. Technically, the code was always wrong, and previous versions of
the framework silently corrected it.
To quote the .NET Framework 4 Migration Issues document: "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... If you have binaries that cannot be updated, you can include
the <NetFx40_PInvokeStackResilience> 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."
An easy way to fix this is to specify the calling convention and make sure it is the same as in the DLL. A __declspec(dllexport) should yield a cdecl format.
[DllImport("foo.dll", CallingConvention = CallingConvention.Cdecl)]
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 ) ?
Use the following code, if say your DLL has the name MyDLL.dll and you want to use the function MyFunction within the Dll
[DllImport("MyDLL.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern void MyFunction();
this worked for me.
In my case (VB 2010 and DLL compiled with Intel Fortran 2011 XE) the problem exists when my application targets .NET Framework 4. If I change targeted framework to version 3.5, then everything works fine as expected.
So, I would guess the reason is something introduced in .Net Framework 4 but I have no idea at the moment which one
Update: The problem was solved by recompiling Fortran DLL and explicitly specifying STDCALL as calling convention for export names in the DLL.
This is the error I am getting while referencing the CDSDK.dll:
A call to PInvoke function 'Canon_Camera_Control!RDC.CameraSDK.cdAPI::CDStartSDK' 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 erorr is on a file called CAMERA.cs it's a part of my project to control my canon camera through the pc.
I was missing this dll file so i downloaded it twice from two places.
At the first time the dll file was 300kb and gave an error but the program didn't stop i used my logger to log out the error:
5/2/2013--11:02 PM ==> Error! CDStartSDK C000060
5/2/2013--11:02 PM ==> Error! CDEnumDeviceReset C0000F1
5/2/2013--11:02 PM ==> Error! CDFinishSDK C0000F1
Then i downloaded the second file which is 298kb and he gave me this error now.
The exception is on CAMERS.cs on line number 929:
err = (UInt32)cdAPI.CDStartSDK(ref Version, 0);
This is a link to my solution/project on my SkyDrive updated including two directores:
CDSDK1 and CDSDK2 in each there is the cdsdk.dll file one is 928kb or so and other 300kb or so.
Each one give a different error.
https://skydrive.live.com/redir?resid=EB1C71C44C3976D5!202&authkey=!AAe7QvxIzBMne1Q
The project name to download is: Canon_Camera_Control
This is the complete exception message for the secon CDSDK.dll file :
PInvokeStackImbalance was detected
Message: A call to PInvoke function 'Canon_Camera_Control!RDC.CameraSDK.cdAPI::CDStartSDK' 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 googled so deep now and didn't find any clue/s about this error/s.
You have the wrong p/invoke signature. Try unsing the P/Invoke Interop Assistant utility (http://clrinterop.codeplex.com/releases/view/14120) to automatically generate the correct marshalling attributes.
I get this error from within a normal C# console program that's consuming a DLL produced as the build output of a C++ CLI project. There I have a simple DumbThing public ref class with a static method. I'd like to simply call that function or at least instantiate one tiny DumbThing object and see that C# can call code that it gets from a C++ CLI born DLL, but it's not working as it throws an error that puzzles me even more:
First-chance exception at 0x000007fefd2acacd (KernelBase.dll) in DumbTest.exe: Microsoft C++ exception: EEFileLoadException * __ptr64 at memory location 0x007fc228..
UPDATE: below the original exception, there's another first chance exception:
First-chance exception at 0x77cace3b (ntdll.dll) in DumbTest.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.
A colleague pointed out to me that it might be a compile time issue (some options), but I don't have any clues what could cause it. Could anyone please provide some starting point hints?
It's probably a bitness issue. If you compiled your C++/CLI project for a specific platform, be sure that your C# project has set its platform accordingly. Default for C# projects is "Any CPU" which causes the JIT compiler to generate x64 code on a 64-bit architecture. If your C++/CLI project was built for x86 then it can't be loaded into a x64 process on a 64-bit machine.