Compilerwarnung (Ebene 2) C4412
'Funktion': Funktionssignatur enthält typ 'type'; C++-Objekte sind unsicher, um zwischen reinem Code und gemischter oder systemeigener Code zu übergeben.
Hinweise
Die Option "/clr:pure compiler" ist in Visual Studio 2015 veraltet und wird in Visual Studio 2017 nicht unterstützt. Wenn Sie Code haben, der rein 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 erfolgt aus einem /clr:pure compiland zu einer Funktion, 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.
Dies ist aufgrund des Unterschieds der Standardaufrufkonventionen zwischen reinem und systemeigenem Code (oder gemischtem systemeigenem und verwaltetem Code) unsicher. Stellen Sie beim Importieren (via dllimport
) einer Funktion in ein /clr:pure compiland sicher, dass die Deklarationen der einzelnen Typen in der Signatur mit denen im Kompiland identisch sind, die die Funktion exportiert (insbesondere bei Unterschieden bei impliziten Aufrufkonventionen).
Eine virtuelle Memberfunktion ist besonders anfällig für unerwartete Ergebnisse. Allerdings sollte auch eine nicht virtuelle Funktion getestet werden, um sicherzustellen, dass Sie die richtigen Ergebnisse erhalten. Wenn Sie sicher sind, dass Sie die richtigen Ergebnisse erhalten, können Sie diese Warnung ignorieren.
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.
// 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
}
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 typen exportiert, die in der Headerdatei definiert sind.
// 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, Test
wird standardmäßig auf __clrcall
. Wenn Sie dieses Programm kompilieren und ausführen (verwenden Sie nicht /c), löst das Programm eine Ausnahme aus.
Im folgenden Beispiel wird C4412 generiert.
// 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
}