Condividi tramite


Avviso del compilatore (livello 2) C4412

'function': la firma della funzione contiene il tipo 'type'; Gli oggetti C++ non sono sicuri per passare tra codice puro e misto o nativo.

Osservazioni:

L'opzione del compilatore /clr:pure è deprecata in Visual Studio 2015 e non supportata in Visual Studio 2017. Se il codice deve essere puro, è consigliabile convertirlo in C#.

Il compilatore ha rilevato una situazione potenzialmente non sicura che potrebbe causare un errore di runtime: viene eseguita una chiamata da / clr:pure compiland a una funzione importata tramite dllimport e la firma della funzione contiene un tipo non sicuro. Un tipo non è sicuro se contiene una funzione membro o ha un membro dati che è un tipo non sicuro o un riferimento indiretto a un tipo non sicuro.

Ciò non è sicuro a causa della differenza nelle convenzioni di chiamata predefinite tra codice puro e nativo (o nativo misto e gestito). Quando si importa (tramite dllimport) una funzione in un /clr:pure compiland, assicurarsi che le dichiarazioni di ogni tipo nella firma siano identiche a quelle nel compiland che esporta la funzione (prestare particolare attenzione alle differenze nelle convenzioni di chiamata implicite).

Una funzione membro virtuale è particolarmente soggetta a risultati imprevisti. Tuttavia, anche una funzione non virtuale deve essere testata per assicurarsi di ottenere i risultati corretti. Se si è certi di ottenere i risultati corretti, è possibile ignorare questo avviso.

C4412 è disattivato per impostazione predefinita. Per altre informazioni, vedere Avvisi del compilatore disattivati per impostazione predefinita e dllexport, dllimport .

Per risolvere questo avviso, rimuovere tutte le funzioni dal tipo .

Esempi

L'esempio seguente genera l'errore 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
}

L'esempio seguente è un file di intestazione che dichiara due tipi. Il Unsafe tipo non è sicuro perché dispone di una funzione membro.

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

Questo esempio esporta funzioni con i tipi definiti nel file di intestazione.

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

La convenzione di chiamata predefinita in una compilazione /clr:pure è diversa da una compilazione nativa. Quando è incluso C4412.h, Test il valore predefinito è __clrcall. Se si compila ed esegue questo programma (non si usa /c), il programma genererà un'eccezione.

L'esempio seguente genera l'errore 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
}