Udostępnij za pośrednictwem


C4412 (poziom 2) ostrzeżenia kompilatora

"Funkcja": funkcja podpis zawiera typ "typ"; Obiekty C++ są niebezpieczne upłynąć między czystego kodu i mieszanym lub macierzystym.

Kompilator wykryto potencjalnie niebezpiecznych sytuacji, która może spowodować błąd w czasie wykonywania: Wykonano wywołanie z /clr:pure compiland do funkcji, która został zaimportowany za pośrednictwem elementu dllimport i podpisu funkcji zawiera typ niebezpieczne.Typ jest niebezpieczna, jeśli zawiera funkcji składowej, lub ma jest typem niebezpieczne lub pośrednia do niebezpiecznego typu element członkowski danych.

To jest niebezpieczne ze względu na różnice w domyślnym konwencje między w trybie macierzystym i czysty kod wywoływania (lub mieszane macierzystych i zarządzanych).Podczas importowania (via dllimport) funkcji do /clr:pure compiland, zapewnić identyczne z tymi compiland, że wywóz funkcję (Uważaj szczególnie o różnicach w niejawny konwencji wywoływania), deklaracje każdego typu w podpisie.

Funkcja członka wirtualnego jest szczególnie podatne na dać nieoczekiwane wyniki.Jednakże-wirtualny funkcję powinny być badane w celu zapewnienia, że aby uzyskać poprawne wyniki.Jeśli masz pewność, że są uzyskiwanie poprawnych wyników, Ostrzeżenie to można zignorować.

Aby uzyskać więcej informacji na /clr:pure, zobacz Jak: Migrowanie do/CLR: czysty (C + +/ CLI).

C4412 jest domyślnie wyłączona.Zobacz Ostrzeżenia kompilatora, które są domyślnie wyłączone i dllexport, dllimport Aby uzyskać więcej informacji.

Aby rozwiązać to ostrzeżenie, należy usunąć wszystkie funkcje związane z typem.

Przykład

Poniższy przykład generuje 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
}

Poniższy przykład jest pliku nagłówka, który deklaruje dwóch typów.Unsafe Typu jest niebezpieczne, ponieważ ma funkcji składowej.

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

Próbka ta wywozu funkcje z typów zdefiniowanych w pliku nagłówkowym.

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

Domyślnie konwencji wywoływania /clr:pure kompilacji różni się od macierzystych kompilacji.Gdy C4412.h jest włączone, Test będzie domyślnie __clrcall.Jeśli skompilować i uruchomić ten program (nie należy używać /c), program wygeneruje wyjątek.

Poniższy przykład generuje 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
}