pinvokestackimbalance — wie kann ich das beheben oder schalten Sie es aus?
Ich wechselte zu von vs2010 vs2008. Genau die gleiche Lösung, außer jetzt jeden einzelnen Aufruf einer C++ - dll liefert eine 'pinvokestackimbalance' Ausnahme.
Diese Ausnahme nicht entlassen werden, im Jahr 2008. Ich habe vollständigen Zugriff auf die C++ - dll und des aufrufenden Anwendung. Dort nicht erscheinen zu sein irgendwelche Probleme mit der pinvoke, aber das problem ist, macht das debugging andere Probleme unmöglich; die IDE ist ständig anhalten, um mir zu sagen, über diese Dinge.
Zum Beispiel, hier ist die C# - Signatur:
[DllImport("ImageOperations.dll")]
static extern void FasterFunction(
[MarshalAs(UnmanagedType.LPArray)]ushort[] inImage, //IntPtr inImage,
[MarshalAs(UnmanagedType.LPArray)]byte[] outImage, //IntPtr outImage,
int inTotalSize, int inWindow, int inLevel);
Hier ist, was es sieht aus wie auf der C++ Seite:
#ifdef OPERATIONS_EXPORTS
#define OPERATIONS_API __declspec(dllexport)
#else
#define OPERATIONS_API __declspec(dllimport)
#endif
extern "C" {
OPERATIONS_API void __cdecl FasterFunction(unsigned short* inArray,
unsigned char* outRemappedImage,
int inTotalSize,
int inWindow, int inLevel);
}
Was ist der Unterschied zwischen vs2010 und vs2008 dazu führen würde, dass diese Ausnahmen geworfen bekommen? Soll ich werden das hinzufügen von einen anderen Satz von Parametern auf die DllImport-Richtlinie?
InformationsquelleAutor mmr | 2010-08-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zuerst verstehen, dass der code falsch ist (und immer war). Die "pInvokeStackImbalance" ist nicht eine Ausnahme, per se, sondern ein verwaltetes debugging assistant. Es wurde standardmäßig deaktiviert in VS2008, aber eine Menge Leute nicht biegen Sie es auf, es ist also standardmäßig in VS2010. Der MDA nicht in den Release-Modus, so dass Sie wird nicht ausgelöst, wenn Sie den build für das release.
In Ihrem Fall, die Aufruf-Konvention ist falsch.
DllImport
standardmäßigCallingConvention.WinApi
, die identisch ist mitCallingConvention.StdCall
für x86-desktop-code. Es sollteCallingConvention.Cdecl
.Kann dies tun, indem Sie die Zeile
[DllImport("ImageOperations.dll")]
werden:Weitere Informationen finden Sie unter dieser MSDN-Referenz
Das ist schon möglich. Diese Besondere Art von stack Ungleichgewicht ist eigentlich etwas gemeinsames haben; es verursacht keine Fehler, sofort, aber langsam verbrauchen die thread-stack. Schließlich, "schlechte Dinge" passieren wird. Die CLR wird meistens in der Lage, um eine
StackOverflowException
, aberusing
,catch
, undfinally
Blöcke wirklich Dinge zu komplizieren, wenn der stack voll ist. Aus diesem Grund, ab .NET 2.0, einStackOverflowException
wird nur den Prozess zu beenden.Mehr Informationen über die interop-Aufruf-Konventionen hier.
Ausgezeichnet, dieser wies mich in die richtige Richtung nach dem Versuch zur update, einige Projekte zu .Net 4.0. Nach dem ändern der Aufrufkonvention in C# - Quellcode zu
Cdecl
hatte ich dann eine änderung machen, um unsere *.h und *.c-Dateien verwenden', __cdecl`.Danke!!! Diese Antwort den Tag gerettet. In meinem Fall, das Problem entstand aus verweisen auf eine Visual C++ 8.0 (Visual Studio 2008) - DLL in eine Visual-Studio-2010-Projekt.
InformationsquelleAutor Stephen Cleary
Ausschalten:
InformationsquelleAutor JGogel
Besser, dieses Problem zu lösen das nicht viel ist schwieriger, hier bin ich zu erwähnen, einige der Methoden, es kann dasselbe wie einige von meinen Freunden erwähnt. Ich arbeite mit PCSC Smartcard-Anwendung verbringe ich rund eine Woche stinksauer hast viel verpasst, endlich die Lösungen.
Für mich seine Arbeit mit PInvoke-Erweiterung, die ich installiert für VS2010 können Sie es hier herunterladen http://www.red-gate.com/products/dotnet-development/pinvoke/
Herunterladen und installieren Sie Sie, Schließen Sie visual studio, und öffnen Sie Sie wieder finden-Verlängerung in der Menüleiste.
Wenn der Fehler wegen der Signatur nicht übereinstimmen, klicken Sie einfach auf PInvoke.net> Insert PInvoke Signatures
Dem neuen Fenster angezeigt, wie unten
Geben Sie den Namen der dll, und klicken Sie auf Suche, die Sie sehen können, die alle Funktionen, die dll im suchergebnis-Fenster Klicken Sie auf die Funktion erhalten Sie eine Signatur für diese Funktion.
Verwenden, dass die Signatur und müssen Sie ändern Ihre Programme entsprechend, die Unterschrift, die Meist den Daten-Typ.
Diese mein problem lösen könnten Sie haben verschiedene problem wie callingConvention oder zusätzliche Attribute benötigen, geben Sie beim importieren der dll.
Happy Coding gut!
Die meisten DLLs nicht gefunden werden kann in dem suchen-Fenster. Schade, denn es sieht ziemlich ordentlich.
InformationsquelleAutor Vijay Kumbhoje
Ich habe dieses problem auch mit VS2010.
Was es ist:
Visual Studio standardmäßig auf 64-bit-code für 'any CPU'.
Die Zeiger auf Variablen (zB. strings) werden nun 64-bit, beim aufrufen der externen Dlls, wo alle Ihre zuverlässige und Vertrauenswürdige Dlls verwenden Sie 32-bit-Zeiger.
Nicht davon ausgehen, es ist etwas falsch mit Ihrem Dlls, gibt es nicht.
Ändern Sie Ihre VS-Einstellungen zu generieren, die X86-code (Express-Versionen von C#)
Ich merke auch, dass, obwohl Computer haben, verdoppelt die macht, alle 12 Monate bei meinem derzeitigen computer mit 1gig RAM, scheint gar nicht schneller als bei meinem ersten 486 mit 4 MB.
Mach dir keine sorgen über die Verwendung von 64-bit-code, es wird nicht schneller oder besser, weil es ist gebaut auf einem riesigen schwerfälligen Objekt-orientierte Turm von aufblasen.
Das hat funktioniert, vielen Dank! Sparte mich Stunden wenn nicht Tage!
InformationsquelleAutor penguinman
Ich versuchte zu rufen-dll mit der
CallingConvention
istThisCall
- und es funktionierte für mich. Hier ist mein code arbeiten mit BLOB-MS-Sql-Server.Mehr unter: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention(v=vs. 110).aspx
InformationsquelleAutor Hao Svit