Teilen über


Compilerwarnung (Ebene 2, deaktiviert) C4412

'Funktion': Funktionssignatur enthält den Typ 'Typ'; C++-Objekte sind unsicher, wenn sie zwischen reinem Code und gemischtem oder systemeigenem ausgetauscht werden.

Hinweise

Die /clr:pure Compileroption ist in Visual Studio 2015 veraltet und wird ab Visual Studio 2017 nicht unterstützt. Wenn Sie Code haben, der rein CLR sein muss, empfehlen wir, ihn zu C# zu portieren.

Der Compiler hat eine potenziell unsichere Situation erkannt, die zu einem Laufzeitfehler führen kann: Ein Aufruf wird von Code, der mit /clr:pure kompiliert wurde, an eine Funktion gemacht, die über dllimport importiert wurde, und die Funktionssignatur enthält einen unsicheren Typ. Ein Typ ist unsicher, wenn er eine Memberfunktion enthält oder über ein Datenmememm verfügt, bei dem es sich um einen unsicheren Typ oder eine Dereferenzierung eines unsicheren Typs handelt.

Dieses Muster ist aufgrund des Unterschieds der Standardaufrufkonventionen zwischen reinem und systemeigenem Code (oder gemischt nativem und verwaltetem Code) unsicher. Stellen Sie beim Importieren einer Funktion über dllimport in mit /clr:pure kompiliertem Code sicher, dass die Deklarationen der einzelnen Typen in der Signatur mit der Signatur im Compiland identisch sind, das die Funktion exportiert; achten Sie besonders auf Unterschiede in den impliziten Aufrufkonventionen.

Eine virtuelle Memberfunktion ist besonders anfällig für unerwartete Ergebnisse. Allerdings sollte auch eine nichtvirtuale Funktion getestet werden, um sicherzustellen, dass Sie die richtigen Ergebnisse erhalten. Diese Warnung kann ignoriert werden, sobald Sie sicherstellen, dass das Ergebnis korrekt ist.

C4412 ist standardmäßig deaktiviert. Weitere Informationen finden Sie unter Compilerwarnungen, die standardmäßig deaktiviert sind , und dllexport, dllimport.

Um diese Warnung zu beheben, entfernen Sie alle Funktionen aus dem Typ.

Beispiele

Im folgenden Beispiel wird C4412 generiert:

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

Das folgende Beispiel ist eine Headerdatei, die zwei Typen deklariert. Der Unsafe Typ ist unsicher, da er über eine Memberfunktion verfügt:

// 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;
};

In diesem Beispiel werden Funktionen mit den in der Headerdatei definierten Typen exportiert:

// 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; }

Die Standardaufrufkonvention in einer /clr:pure Kompilierung unterscheidet sich von einer systemeigenen Kompilierung. Wenn C4412.h enthalten ist, wird Test standardmäßig auf __clrcall gesetzt.

Im folgenden Beispiel wird C4412 generiert und zur Laufzeit eine Ausnahme ausgelöst:

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