programing

pinvokestackimbalance — 어떻게 고치거나 끌 수 있습니까?

nasanasas 2020. 10. 31. 09:46
반응형

pinvokestackimbalance — 어떻게 고치거나 끌 수 있습니까?


방금 vs2008에서 vs2010으로 전환했습니다. C ++ dll에 대한 모든 단일 호출이 'pinvokestackimbalance'예외를 생성한다는 점을 제외하면 정확히 동일한 솔루션입니다.

이 예외는 2008 년에 발생하지 않습니다. C ++ dll 및 호출 응용 프로그램에 대한 완전한 액세스 권한이 있습니다. pinvoke에 문제가없는 것 같지만이 문제로 인해 다른 문제를 디버깅 할 수 없습니다. IDE는 이러한 사항에 대해 알려주기 위해 끊임없이 멈 춥니 다.

예를 들어 다음은 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);

다음은 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);

}

이러한 예외가 발생하는 원인이되는 vs2010과 vs2008의 차이점은 무엇입니까? DllImport 지시문에 다른 매개 변수 세트를 추가해야합니까?


첫째, 코드가 잘못되었다는 것을 이해하십시오 (항상 그렇습니다). "pInvokeStackImbalance"는 그 자체로 예외가 아니라 관리되는 디버깅 도우미입니다. VS2008에서는 기본적으로 꺼져 있지만 많은 사람들이 켜지지 않았기 때문에 VS2010에서는 기본적으로 켜져 있습니다. MDA는 릴리스 모드에서 실행되지 않으므로 릴리스 용으로 빌드하는 경우 트리거되지 않습니다.

귀하의 경우 호출 규칙이 잘못되었습니다. DllImport기본값은 CallingConvention.WinApi이며 CallingConvention.StdCallx86 데스크톱 코드의 경우와 동일합니다 . 이어야합니다 CallingConvention.Cdecl.

[DllImport("ImageOperations.dll")]을 다음과 같이 편집하여 수행 할 수 있습니다.

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

자세한 내용은 이 MSDN 참조를 참조하십시오.


끄려면 :

  1. CTRL + ALT + E
  2. "Managed Debugging Assistants"에서 PInvokeStackImbalance를 선택 취소하십시오.

이 문제를 해결하는 것이별로 어렵지 않습니다. 여기서 몇 가지 방법을 언급하고 있습니다. 위에서 언급 한 일부 친구와 동일 할 수 있습니다. 저는 PCSC와 함께 일하고 있습니다. 제가 약 1 주일을 소비하는 스마트 카드 응용 프로그램을 사용하고 있습니다. 많은 변경 사항을 거쳐 마침내 솔루션을 얻었습니다.

저에게 VS2010 용으로 설치 한 PInvoke Extension에 대한 작업은 여기 http://www.red-gate.com/products/dotnet-development/pinvoke/에서 다운로드 할 수 있습니다 .

다운로드하여 설치하고 Visual Studio를 닫고 다시 열면 메뉴 모음에서 확장 프로그램을 찾을 수 있습니다. 여기에 이미지 설명 입력

서명이 일치하지 않아 오류가 발생한 경우 PInvoke.net> Insert PInvoke Signatures를 클릭하면됩니다.

새 창이 아래와 같이 나타납니다. 여기에 이미지 설명 입력

Enter the name of the dll and click on search you can see the all the functions of that dll in search result window, Click on the function you will get a signature for that particular Function.

Use that signature and you need to modify your programs according to that Signature, Mostly the data Type.

This solve my problem you might have different problem like callingConvention or additional attributes need to specify while importing dll.

Happy Coding Be well!


I got this problem also when using VS2010. What it is: Visual Studio defaults to 64 bit code for 'any CPU'. The pointers to variables (eg. strings) now become 64 bit when calling your external Dlls, where as all your reliable and trusted Dlls use 32 bit pointers.

Don't assume there is anything wrong with your Dlls, there isn't.

Change your VS settings to generate X86 code like this (Express versions of C#)

  1. go to Tools -> Options.
  2. In the bottom-left corner of the Options dialog, check the box that says, "Show all settings".
  3. In the tree-view on the left hand side, select "Projects and Solutions".
  4. In the options on the right, check the box that says, "Show advanced build configuraions."
  5. Click OK.
  6. Go to Build -> Configuration Manager...
  7. In the Platform column next to your project, click the combobox and select "".
  8. In the "New platform" setting, choose "x86".
  9. Click OK.
  10. Click Close.

또한 컴퓨터의 전력이 12 개월마다 두 배가 되었음에도 불구하고 현재 1gig의 RAM이 장착 된 컴퓨터는 4Meg를 장착 한 첫 번째 486보다 빠르지 않은 것 같습니다. 64 비트 코드를 사용하는 것에 대해 걱정하지 마십시오. 이것은 거대하고 성가신 객체 지향 타워에 구축 되었기 때문에 더 빠르거나 더 나아질 수는 없습니다.


나는 dll을 CallingConventionis 로 호출하려고 시도 ThisCall했고 그것은 나를 위해 일했습니다. 다음은 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);

자세한 내용 : https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention(v=vs.110).aspx

참고 URL : https://stackoverflow.com/questions/3506796/pinvokestackimbalance-how-can-i-fix-this-or-turn-it-off

반응형