P/Invoke의 Cdecl/__stdcall 충돌 이해
C#과 C를 연결하는 P/Invoke는 일치하는 호출 규칙을 사용하여 적절한 인수 전달 및 스택 관리를 보장합니다. __stdcall
규칙을 사용하는 C 함수가 기본(종종 cdecl
) P/Invoke 규칙
문제의 근원
다른 호출 규칙은 스택 정리를 다르게 처리합니다.
__stdcall
: Windows API 및 COM에서 광범위하게 사용되며 호출 수신자(C 함수)는 스택 정리를 담당합니다.__cdecl
: 호출자(C# 코드)가 스택 정리를 처리하는 기본 C 호출 규칙입니다.__thiscall
: C 멤버 함수에 사용됩니다. 복잡성으로 인해 P/Invoke에서는 직접 지원되지 않습니다.불일치의 결과
C 코드에 extern "C"
을 추가하고 C# CallingConvention.Cdecl
속성에 DllImport
을 지정하는 것만으로는 문제가 해결되지 않습니다. 정리 책임이 다르면 스택 손상이 발생하여 즉각적인 디버거 경고 없이도 잠재적으로 충돌이나 미묘하고 디버그하기 어려운 오류가 발생할 수 있습니다. 스택이 두 번 정리되어 예측할 수 없는 동작이 발생할 수 있습니다.
해결책: 일관된 규칙
핵심은 일관성입니다. __cdecl
을 명시적으로 사용하도록 C 함수 선언을 수정합니다. extern "C" int __stdcall InvokedFunction(int);
을 extern "C" int __cdecl InvokedFunction(int);
으로 바꿉니다. 그런 다음 C# DllImport
속성이 다음과 일치하는지 확인하세요.
<code class="language-csharp">[DllImport("CPlusPlus.dll", ExactSpelling = true, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]</code>
핵심 요약
신뢰할 수 있는 P/Invoke 상호 운용성을 위해서는 호출 규칙에 세심한 주의가 필요합니다. C와 C# 간의 일관된 규칙을 사용하면 스택 불균형이 제거되고 코드의 전반적인 견고성이 향상됩니다.
위 내용은 __stdcall C 및 Cdecl C# 호출이 P/Invoke에서 충돌하는 이유는 무엇이며 이를 어떻게 해결할 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!