Share via


Advertencia del compilador (nivel 2) C4412

function’: la signatura de función contiene el tipo ‘type’; no es seguro pasar los objetos de C++ entre código puro y mixto o nativo.

Comentarios

La opción del compilador /clr:pure está en desuso en Visual Studio 2015 y no se admite en Visual Studio 2017. Si tiene código que debe ser puro, le recomendamos que lo porte a C#.

El compilador detectó una situación potencialmente no segura que podría provocar un error en tiempo de ejecución: se realiza una llamada desde un compilando /clr:pure a una función que se importó a través de dllimport y la signatura de función contiene un tipo no seguro. Un tipo no es seguro si contiene una función miembro o tiene un miembro de datos que es un tipo no seguro o una 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 nativo mixto y administrado). Al importar (a través de dllimport) una función en un compilando /clr:pure, asegúrese de que las declaraciones de cada tipo de la firma son idénticas a las del compilado que exporta la función (siendo especialmente cuidadosa sobre las diferencias en las convenciones de llamada implícitas).

Una función miembro virtual es especialmente propensa a dar resultados inesperados. Sin embargo, incluso una función no virtual debe probarse para asegurarse de que obtiene los resultados correctos. Si está seguro de que obtiene los resultados correctos, puede omitir esta advertencia.

C4412 está desactivado de forma predeterminada. Vea Advertencias del compilador desactivadas de forma predeterminada y dllexport, dllimport para más información.

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

Ejemplos

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, el valor predeterminado Test es __clrcall. Si compila y ejecuta este programa (no use /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
}