'function': 함수 서명에 'type' 형식이 포함되어 있습니다. C++ 개체는 순수 코드와 혼합 또는 네이티브 간에 전달하는 것이 안전하지 않습니다.
설명
/clr:pure 컴파일러 옵션은 Visual Studio 2015에서 더 이상 사용되지 않으며 Visual Studio 2017부터 지원되지 않습니다. CLR 순수해야 하는 코드가 있는 경우 C#으로 이식하는 것이 좋습니다.
컴파일러가 /clr:pure로 컴파일된 코드에서 dllimport을 통해 가져온 함수로 호출 시도가 이루어졌으며 해당 함수 서명에 안전하지 않은 형식이 포함돼 있어 런타임 오류가 발생할 수 있는 잠재적으로 위험한 상황을 감지했습니다. 형식이 멤버 함수를 포함하거나 안전하지 않은 형식이거나 안전하지 않은 형식에 대한 간접 참조인 데이터 멤버가 있는 경우 안전하지 않습니다.
이 패턴은 순수 코드와 네이티브 코드(또는 혼합 네이티브 및 관리 코드) 간의 기본 호출 규칙의 차이로 인해 안전하지 않습니다. 컴파일된 dllimport코드로 함수 /clr:pure 를 가져올 때 시그니처의 각 형식 선언이 함수를 내보내는 컴파일랜드의 서명과 동일한지 확인합니다(특히 암시적 호출 규칙의 차이점에 주의).
가상 멤버 함수는 특히 예기치 않은 결과를 제공하는 경향이 있습니다. 그러나 올바른 결과를 얻을 수 있도록 비가상 함수도 테스트해야 합니다. 결과가 올바른지 확인하면 이 경고를 무시할 수 있습니다.
C4412는 기본적으로 꺼져 있습니다. 자세한 내용은 기본적으로 꺼져 있는 컴파일러 경고 및 dllexport. dllimport
이 경고를 해결하려면 형식에서 모든 함수를 제거합니다.
예제
다음 예제에서는 C4412를 생성합니다.
// 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입니다.
런타임에 예외를 던지고 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
}