Udostępnij za pośrednictwem


Ostrzeżenie kompilatora (poziom 2) C4412

"Funkcja": funkcja podpis zawiera typ "typ"; Z obiektami C++ są wystarczająco bezpieczne, aby przejść między czystego kodu i mieszanym lub macierzystym.

Kompilator wykryto potencjalnie niebezpiecznych sytuacji, która może spowodować błąd w czasie wykonywania: wywołanie jest dokonywana z /clr:pure compiland do funkcji, która została zaimportowana za pośrednictwem elementu dllimport i funkcja podpis zawiera niebezpiecznego typu.Typ jest bezpieczna, jeśli zawiera funkcję członka lub ma jest niebezpieczny typ lub pośrednia niebezpiecznego typu element członkowski danych.

To jest niebezpieczny, ze względu na różnice w domyślnym konwencje między czystej i macierzysty kod wywoływania (lub mieszane macierzystego i zarządzane).Podczas importowania (via dllimport) funkcja do /clr:pure compiland, zapewnienia, że deklaracje każdego typu w podpisie są identyczne z tymi na compiland, że wywóz funkcja (uważając, zwłaszcza dotyczące różnic w konwencji wywoływania niejawna).

Funkcja członka wirtualnego jest szczególnie podatne na nieoczekiwane wyniki. Jednak nawet nie wirtualnym funkcji powinny być badane Aby uzyskać poprawne wyniki.Jeśli masz pewność, że otrzymujesz prawidłowych wyników, można zignorować to ostrzeżenie.

Aby uzyskać więcej informacji na temat funkcji /clr:pure, zobacz Porady: migracja do /clr:pure (C++/CLI).

C4412 jest domyślnie wyłączona.Zobacz Domyślnie wyłączone ostrzeżenia kompilatora 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 plik nagłówka, który deklaruje dwa typy.Unsafe Typu jest niebezpieczna, ponieważ ma ona 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;
};

W tym przykładzie eksportuje funkcji z typów zdefiniowanych w pliku nagłówka.

// 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 macierzystego kompilacji. Gdy jest włączone, C4412.h Test jest domyślnie do __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
}