카테고리 없음

왜 이 간단한 예제에서 "PInvokeStackImbalance was detected" 오류가 발생하나요?

스택큐힙리스트 2023. 11. 17. 10:39
반응형

저는 매우 간단한 PInvoke 샘플을 만들고 있습니다:


extern C __declspec(dllexport) int Add(int a, int b)
{
return a + b;
}
[DllImport(CommonNativeLib.dll)]
extern public static int Add(int a, int b);
return NativeMethods.Add(a, b);

하지만 위의 NativeMethods.Add 메소드를 호출할 때마다 다음의 관리되는 디버그 어시스턴트를 얻습니다:



PInvokeStackImbalance이 감지되었습니다.
메시지: 'CommonManagedLib!CommonManagedLib.NativeMethods::Add' PInvoke 함수 호출은 스택을 균형잡지 않았습니다. 이는 관리되는 PInvoke 시그니처가 비관리 대상 시그니처와 일치하지 않기 때문일 가능성이 있습니다. 호출 규약 및 PInvoke 시그니처의 매개변수가 대상 비관리 시그니처와 일치하는지 확인하세요.


호출은 예상된 반환값과 함께 완료됩니다. 그러나 MDA 메시지가 나타나는 것은 귀찮고 걱정이 됩니다. 아직 PInvoke를 완전히 이해하지 못하고 있지만, 읽은 내용으로는 나의 시그니처가 올바르다고 확신합니다. 제가 무엇을 잘못하고 있는 걸까요?


이 모든 것은 32-bit 운영체제에서 진행됩니다.

답변 1

대신 둘 다 사용해야합니다.


[DllImport(CommonNativeLib.dll, CallingConvention = CallingConvention.Cdecl)]

또는


extern C __declspec(dllexport) int __stdcall Add(int a, int b) ...

왜냐하면 일반 C 함수는 Windows API 함수와는 다르게 작동하기 때문에 호출 규약이 다르며, 파라미터를 전달하는 방식이 다릅니다. (에러에서 암시되었습니다.)

답변 2

**한국어 SEO를 고려한 PInvokeStackImbalance was detected 오류 원인과 해결 방법**
PInvokeStackImbalance was detected 오류 메시지는 귀하가 진행 중인 단순한 예제에서 발생하는 이유에 대해 설명하고 해결 방법을 제시합니다. 이 오류는 일반적으로 .NET 언어(예: C#)와 네이티브 언어(예: C++) 간 상호 운용 기능을 사용할 때 발생하는 경우가 많습니다.
.NET Framework는 관리 코드와 네이티브 코드 간의 상호 운용성을 제공하기 위한 P/Invoke (Platform Invocation Services)을 제공합니다. P/Invoke를 사용하면 .NET 코드에서 네이티브 DLL 함수를 호출하거나, 네이티브 코드에서 .NET 메서드를 호출할 수 있습니다. 그러나 이러한 상호 운용성을 사용할 때 올바른 균형을 유지해야 합니다. 그렇지 않으면 PInvokeStackImbalance was detected 오류가 발생합니다.
일반적으로 이 오류가 발생하는 경우는 다음과 같습니다:
1. 호출자(예: .NET 코드)와 DLL 함수의 호출규약이 일치하지 않는 경우.
2. 호출된 DLL 함수가 사용하는 스택으로 인한 균형의 오류.
이 오류를 해결하기 위해서는 다음과 같은 조치를 취할 수 있습니다:
1. DLL 함수의 호출규약 검토: 호출하는 함수와 호출되는 DLL 함수 간에 호출규약이 일치하는지 확인해야 합니다. 호출규약은 함수 호출 방식과 매개변수 전달 방법에 대한 규칙을 정의합니다. 예를 들어, 호출자에서 `stdcall` 호출규약을 사용하고 있는데 호출될 DLL 함수는 `cdecl` 호출규약을 사용한다면, 이러한 균형 오류가 발생할 수 있습니다. 따라서 호출되는 DLL 함수의 호출규약을 확인하고, 이에 맞춰 호출하는 함수를 수정해야 합니다.
2. `EntryPoint` 속성 수정: P/Invoke를 통해 호출되는 DLL 함수의 진입점 부분(Entry Point)을 확인해야 합니다. DLL 함수의 진입점이 올바르게 지정되지 않은 경우에도 이 오류가 발생할 수 있습니다. 이 경우 `DllImport` 특성의 `EntryPoint` 속성을 사용하여 올바른 진입점을 지정해야 합니다.
3. 스택 상태 조정: 경우에 따라 호출되는 DLL 함수가 .NET Framework와 상호 작용하기 위해 스택 상태를 특정 방식으로 조정해야 할 수도 있습니다. DLL 함수 내에서 스택을 조작하는 코드가 있는 경우, 해당 코드를 정확하게 이해하고 .NET과의 상호 작용을 위해 스택을 올바르게 조정해야 합니다.
이처럼 PInvokeStackImbalance was detected 오류는 .NET 언어와 네이티브 언어 간의 상호 운용 기능을 사용할 때 발생할 수 있습니다. 오류를 해결하기 위해서는 호출한 함수와 호출되는 DLL 함수 간의 호출규약을 일치시키고, `EntryPoint` 속성을 수정하며, 필요한 경우 스택 상태를 조정해야 합니다. 이렇게 오류를 해결하여 더 원활한 상호 운용성을 달성할 수 있습니다.

반응형