pinvokestackimbalance-jak to naprawić lub wyłączyć?

Właśnie przełączyłem się na vs2010 z vs2008. Dokładnie to samo rozwiązanie, tyle że teraz każde wywołanie biblioteki dll C++ daje wyjątek "pinvokestackimbalance".

Ten wyjątek nie zostanie zwolniony w 2008 roku. Mam pełny dostęp do C++ dll i do aplikacji wywołującej. Wydaje się, że nie ma żadnego problemu z pinvoke, ale ten problem sprawia, że debugowanie innych problemów jest niemożliwe; IDE zatrzymuje się nieustannie, aby powiedzieć mi o tych rzeczach.

Dla przykład, oto podpis C#:

    [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);

Oto Jak to wygląda po stronie C++:

#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);

}

Czym różni się vs2010 od vs2008, że te wyjątki zostaną wyrzucone? Czy powinienem dodać inny zestaw parametrów do dyrektywy DllImport?

5 answers

Najpierw zrozum, że kod jest zły (i zawsze był). "PInvokeStackImbalance" nie jest wyjątkiem per se, ale zarządzanym asystentem debugowania. Był domyślnie wyłączony w VS2008, ale wiele osób go nie włączyło, więc jest domyślnie włączony w VS2010. MDA nie działa w trybie Release, więc nie uruchomi się, jeśli zbudujesz go do wydania.

W Twoim przypadku, konwencja wywołująca jest niepoprawna. DllImport domyślnie CallingConvention.WinApi, który jest identyczny z CallingConvention.StdCall dla kodu pulpitu x86. Powinno be CallingConvention.Cdecl.

Można to zrobić edytując linię [DllImport("ImageOperations.dll")] do:

[DllImport("ImageOperations.dll", CallingConvention = CallingConvention.Cdecl)]

Aby uzyskać więcej informacji, zobacz ten odnośnik MSDN

 147
Author: Stephen Cleary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-06 19:03:11

Aby go wyłączyć:

  1. CTRL + ALT + E
  2. w sekcji "Managed Debugging Assistants" odznacz PInvokeStackImbalance.
 45
Author: JGogel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-13 07:40:31

Lepiej rozwiązać ten problem nie jest zbyt trudne tutaj wspominam niektóre z metod, może to samo, jak niektórzy z moich przyjaciół wymienionych powyżej. Pracuję z PCSC Smartcard aplikacji spędzam około jednego tygodnia, wkurzony zrobił wiele zmian w końcu dostał rozwiązania.

Dla mnie jego praca z rozszerzeniem PInvoke, które zainstalowałem dla VS2010 można pobrać tutaj http://www.red-gate.com/products/dotnet-development/pinvoke/

Pobierz i zainstaluj, Zamknij visual studio i otwórz ponownie rozszerzenie można znaleźć na pasku Menu. Tutaj wpisz opis obrazka

Jeśli błąd wynika z nie pasującego podpisu wystarczy kliknąć na PInvoke.net> Insert PInvoke Signatures

Nowe okno pojawi się jak poniżej Tutaj wpisz opis obrazka

Wprowadź nazwę dll i kliknij Szukaj możesz zobaczyć wszystkie funkcje tego dll w oknie wyników wyszukiwania, kliknij na funkcję otrzymasz podpis dla tej konkretnej funkcji.

Użyj tego podpisu i Ty musisz zmodyfikować swoje programy zgodnie z tym podpisem, głównie typem danych.

To rozwiązuje mój problem możesz mieć inny problem, taki jak callingConvention lub dodatkowe atrybuty, które należy określić podczas importowania dll.

Happy Coding Be well!

 8
Author: AirCodeOne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-04 10:21:31

Mam ten problem również podczas korzystania z VS2010. Co to jest: Domyślnie program Visual Studio ma 64-bitowy kod dla "dowolnego procesora". Wskaźniki do zmiennych (np. ciągi) stają się teraz 64-bitowe podczas wywoływania zewnętrznych bibliotek DLL, gdzie jak wszystkie niezawodne i zaufane biblioteki DLL używają 32-bitowych wskaźników.

Nie zakładaj, że coś jest nie tak z Twoimi bibliotekami DLL, nie ma.

Zmień ustawienia VS, aby wygenerować kod X86 w ten sposób (ekspresowe wersje C#)

  1. przejdź do Narzędzia - > Opcje.
  2. w lewym dolnym rogu okna dialogowego Opcje zaznacz pole z napisem "Pokaż wszystkie ustawienia".
  3. w widoku drzewa po lewej stronie wybierz "projekty i rozwiązania".
  4. w opcjach po prawej stronie zaznacz pole " Pokaż zaawansowane konfiguracje budowania."
  5. Kliknij OK.
  6. przejdź do Build - > Configuration Manager...
  7. w kolumnie Platforma obok Twojego projektu, kliknij combobox i wybierz "".
  8. w ustawieniu "nowa platforma", wybierz "x86".
  9. Kliknij OK.
  10. Kliknij Zamknij.

Zauważyłem również, że mimo, że komputery podwoiły moc co 12 miesięcy, mój obecny komputer z 1GIG pamięci RAM, wydaje się nie szybszy niż mój pierwszy 486 z 4 Meg. Nie martw się o użycie kodu 64-bitowego, nie będzie szybszy ani lepszy, ponieważ jest zbudowany na ogromnej kłopotliwej obiektowej wieży wzdęcia.

 3
Author: penguinman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-13 07:42:58

Próbowałem zadzwonić do dll z CallingConvention jest ThisCall i zadziałało dla mnie. Oto Mój kod pracujący z BLOB MS SQL Server.

[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);
Więcej na: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention(v=vs.110).aspx
 0
Author: Hao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-09 04:23:43