Ich habe gerade von vs2008 zu vs2010 gewechselt. Genau dieselbe Lösung, außer dass jetzt jeder einzelne Aufruf einer C ++ - DLL eine Ausnahme für "pinvokestackimbalance" ergibt.
Diese Ausnahme wird 2008 nicht ausgelöst. Ich habe vollständigen Zugriff auf die C ++ - DLL und die aufrufende Anwendung. Es scheint kein Problem mit dem Pinvoke zu geben, aber dieses Problem macht das Debuggen anderer Probleme unmöglich. Die IDE hält ständig an, um mir von diesen Dingen zu erzählen.
Hier ist zum Beispiel 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);
So sieht es auf der C ++ - Seite aus:
#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 anders zwischen vs2010 und vs2008, was dazu führen würde, dass diese Ausnahmen ausgelöst werden? Sollte ich der DllImport-Direktive einen anderen Parametersatz hinzufügen?
StackOverflowException
, aberusing
, zu erhöhencatch
, undfinally
Blöcke erschweren die Sache wirklich, wenn der Stapel voll ist. Aus diesem Grund wird ab .NET 2.0StackOverflowException
der Prozess nur beendet.Cdecl
ich die Aufrufkonvention in der C # -Quelle in geändert hatte, musste ich eine Änderung an unseren * .h- und * .c-Dateien vornehmen, um '__cdecl` zu verwenden.So schalten Sie es aus:
quelle
Besser, um dieses Problem zu lösen, es ist hier nicht sehr schwierig. Ich erwähne einige der Methoden, es kann dasselbe sein wie einige meiner oben erwähnten Freunde. Ich arbeite mit PCSC, einer Smartcard-Anwendung, die ich ungefähr eine Woche lang verbringe. Ich bin sauer, habe viele Änderungen vorgenommen und endlich die Lösungen gefunden.
Für mich ist die Arbeit mit PInvoke Extension, die ich für VS2010 installiert habe, hier erhältlich. Http://www.red-gate.com/products/dotnet-development/pinvoke/
Laden Sie es herunter und installieren Sie es. Schließen Sie Visual Studio und öffnen Sie es erneut. Die Erweiterung finden Sie in der Menüleiste.
Wenn der Fehler auf eine nicht übereinstimmende Signatur zurückzuführen ist, klicken Sie einfach auf PInvoke.net> PInvoke-Signaturen einfügen
Das neue Fenster wird wie folgt angezeigt
Geben Sie den Namen der DLL ein und klicken Sie auf Suchen. Sie können alle Funktionen dieser DLL im Suchergebnisfenster sehen. Klicken Sie auf die Funktion, für die Sie eine Signatur für diese bestimmte Funktion erhalten.
Verwenden Sie diese Signatur, und Sie müssen Ihre Programme entsprechend dieser Signatur, hauptsächlich dem Datentyp, ändern.
Dies löst mein Problem. Möglicherweise haben Sie ein anderes Problem wie das Aufrufen von Convention oder zusätzliche Attribute, die beim Importieren der DLL angegeben werden müssen.
Happy Coding Sei gesund!
quelle
Ich habe dieses Problem auch bei der Verwendung von VS2010. Was es ist: Visual Studio verwendet standardmäßig 64-Bit-Code für 'jede CPU'. Die Zeiger auf Variablen (z. B. Zeichenfolgen) werden jetzt 64-Bit, wenn Sie Ihre externen DLLs aufrufen, wobei alle Ihre zuverlässigen und vertrauenswürdigen DLLs 32-Bit-Zeiger verwenden.
Gehen Sie nicht davon aus, dass mit Ihren DLLs etwas nicht stimmt.
Ändern Sie Ihre VS-Einstellungen, um X86-Code wie folgt zu generieren (Express-Versionen von C #).
Ich stelle auch fest, dass mein aktueller Computer mit 1 GB RAM nicht schneller zu sein scheint als mein erster 486 mit 4 Meg., Obwohl sich die Leistung der Computer alle 12 Monate verdoppelt hat. Machen Sie sich keine Sorgen um die Verwendung von 64-Bit-Code, er wird nicht schneller oder besser sein, da er auf einem riesigen, schwerfälligen, objektorientierten Turm aus Bloat aufgebaut ist.
quelle
Ich habe versucht, DLL mit dem
CallingConvention
is aufzurufenThisCall
und es hat bei mir funktioniert. Hier ist mein Code, der mit BLOB MS SQL Server arbeitet.[DllImport("sqlncli11.dll", SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.ThisCall)] private static extern SafeFileHandle OpenSqlFilestream( string FilestreamPath, UInt32 DesiredAccess, UInt32 OpenOptions, byte[] FilestreamTransactionContext, UInt32 FilestreamTransactionContextLength, Int64 AllocationSize);
Weitere Informationen finden Sie unter : https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention(v=vs.110).aspx
quelle