Advertencia del compilador (nivel 2) C4412

Actualización: noviembre 2007

Mensaje de error

'función' : la firma de la función contiene el tipo 'tipo'; no es seguro pasar los objetos de C++ entre código puro y mixto o nativo.
'function' : function signature contains type 'type'; C++ objects are unsafe to pass between pure code and mixed or native.

El compilador detectó una situación potencialmente no segura, que podría provocar un error en tiempo de ejecución: se está realizando una llamada desde una operación de compilación /clr:pure a una función que se importó mediante dllimport y la firma de la función contiene un tipo no seguro. Un tipo no es seguro si contiene una función miembro o si tiene un miembro de datos de tipo no seguro o un direccionamiento indirecto a un tipo no seguro.

Esto no es seguro debido a la diferencia en las convenciones de llamada predeterminadas entre código puro y nativo (o mixto nativo y administrado). Cuando importe (mediante dllimport) una función en una operación de compilación /clr:pure, asegúrese de que las declaraciones de cada tipo en la firma sean idénticas a las de la operación de compilación que exporta la función (con especial atención en las diferencias en las convenciones de llamada implícitas).

Una función miembro virtual es especialmente propensa a proporcionar resultados inesperados. Sin embargo, incluso una función no virtual se debería probar para garantizar que obtiene los resultados correctos. Si está seguro que está obteniendo los resultados correctos, puede hacer caso omiso de esta advertencia.

Para obtener más información sobre /clr:pure, vea Cómo: Migrar a /clr:pure.

La advertencia C4412 está desactivada de manera predeterminada. Para obtener más información, vea Compiler Warnings That Are Off by Default y dllexport, dllimport.

Para resolver esta advertencia, quite todas las funciones del tipo.

Ejemplo

El ejemplo siguiente genera el error 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
}

El ejemplo siguiente es un archivo de encabezado que declara dos tipos. El tipo Unsafe no es seguro porque tiene una función miembro.

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

Este ejemplo exporta funciones con los tipos definidos en el archivo de encabezado.

// 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 convención de llamada predeterminada en una compilación /clr:pure es diferente de una compilación nativa. Cuando se incluye C4412.h, Test se establecerá de forma predeterminada en __clrcall. Si compila y ejecuta este programa (no utilice /c), el programa producirá una excepción.

El ejemplo siguiente genera el error 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
}