컴파일러 경고(수준 2) C4412
'function': 함수 서명에 'type' 형식이 포함되어 있습니다. C++ 개체는 순수 코드와 혼합 또는 네이티브 간에 전달하는 것이 안전하지 않습니다.
설명
/clr:pure 컴파일러 옵션은 Visual Studio 2015에서 더 이상 사용되지 않으며 Visual Studio 2017에서는 지원되지 않습니다. 순수해야 하는 코드가 있는 경우 C#으로 이식하는 것이 좋습니다.
컴파일러는 런타임 오류가 발생할 수 있는 잠재적으로 안전하지 않은 상황을 감지했습니다. /clr:pure compiland에서 dllimport를 통해 가져온 함수로 호출되고 함수 서명에 안전하지 않은 형식이 포함되어 있습니다. 형식이 멤버 함수를 포함하거나 안전하지 않은 형식이거나 안전하지 않은 형식에 대한 간접 참조인 데이터 멤버가 있는 경우 안전하지 않습니다.
순수 코드와 네이티브 코드(또는 혼합 네이티브 및 관리 코드) 간의 기본 호출 규칙 차이로 인해 안전하지 않습니다. 함수를 dllimport
/clr:pure compiland로 가져올 때 서명에 있는 각 형식의 선언이 함수를 내보내는 컴파일랜드의 선언과 동일한지 확인합니다(특히 암시적 호출 규칙의 차이점에 주의).
가상 멤버 함수는 특히 예기치 않은 결과를 제공하는 경향이 있습니다. 그러나 올바른 결과를 얻을 수 있도록 가상이 아닌 함수도 테스트해야 합니다. 올바른 결과를 얻고 있다고 확신하는 경우 이 경고를 무시할 수 있습니다.
C4412는 기본적으로 꺼져 있습니다. 자세한 내용은 기본적으로 해제된 컴파일러 경고 및 dllexport, dllimport를 참조하세요.
이 경고를 해결하려면 형식에서 모든 함수를 제거합니다.
예제
다음 샘플에서는 C4412를 생성합니다.
// C4412.cpp
// compile with: /c /W2 /clr:pure
#pragma warning (default : 4412)
struct Unsafe {
virtual void __cdecl Test();
};
struct Safe {
int i;
};
__declspec(dllimport) Unsafe * __cdecl func();
__declspec(dllimport) Safe * __cdecl func2();
int main() {
Unsafe *pUnsafe = func(); // C4412
// pUnsafe->Test();
Safe *pSafe = func2(); // OK
}
다음 샘플은 두 가지 형식을 선언하는 헤더 파일입니다. Unsafe
멤버 함수가 있으므로 형식이 안전하지 않습니다.
// C4412.h
struct Unsafe {
// will be __clrcall if #included in pure compilation
// defaults to __cdecl in native or mixed mode compilation
virtual void Test(int * pi);
// try the following line instead
// virtual void __cdecl Test(int * pi);
};
struct Safe {
int i;
};
이 샘플에서는 헤더 파일에 정의된 형식을 사용하여 함수를 내보냅니다.
// C4412_2.cpp
// compile with: /LD
#include "C4412.h"
void Unsafe::Test(int * pi) {
*pi++;
}
__declspec(dllexport) Unsafe * __cdecl func() { return new Unsafe; }
__declspec(dllexport) Safe * __cdecl func2() { return new Safe; }
/clr:pure 컴파일의 기본 호출 규칙은 네이티브 컴파일과 다릅니다. C4412.h가 포함 Test
되면 기본값은 .입니다 __clrcall
. 이 프로그램을 컴파일하고 실행하면(/c를 사용하지 않음) 프로그램이 예외를 throw합니다.
다음 샘플에서는 C4412를 생성합니다.
// C4412_3.cpp
// compile with: /W2 /clr:pure /c /link C4412_2.lib
#pragma warning (default : 4412)
#include "C4412.h"
__declspec(dllimport) Unsafe * __cdecl func();
__declspec(dllimport) Safe * __cdecl func2();
int main() {
int n = 7;
Unsafe *pUnsafe = func(); // C4412
pUnsafe->Test(&n);
Safe *pSafe = func2(); // OK
}