다음을 통해 공유


컴파일러 경고(수준 2, 해제) C4412

'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
}