Partilhar via


Aviso do compilador (nível 2) C4412

função “”: a assinatura da função contém o tipo “tipo”; Os objetos C++ não são seguras ser transcorrido entre o código puro e misto ou nativo.

O compilador detectou uma situação possivelmente não seguro que pode resultar em um erro de tempo de execução: uma chamada está sendo feita de um compiland de /clr:pure a uma função que foi importada pelo dllimport e a assinatura da função contém um tipo não seguros. Um tipo é unsafe se contiver uma função de membro ou um membro de dados que é um tipo não seguro ou uma ação indireta a um tipo não seguros.

Isso é unsafe devido à diferença nas convenções padrão de chamada entre o código puro e nativo ou nativo (misto e gerenciado). Ao importar (por meio de dllimport) uma função em um compiland de /clr:pure , assegure que as declarações de cada tipo na assinatura são idênticas a aquelas em compiland que exporta a função (sendo especialmente cuidado as diferenças em convenções implícitas de chamada).

Uma função de membro virtual é especialmente polarizada de resultados inesperados. Porém, mesmo uma função não virtual deve ser testada para garantir que terá os resultados corretos. Se você tiver certeza de que você está obtendo os resultados corretos, você pode ignorar esse aviso.

Para obter mais informações sobre /clr:pure, consulte: Como migrar para /clr:pure (C++/CLI).

C4412 é desativada por padrão. Consulte Avisos de compilador desativados por padrão e dllexport, dllimport para obter mais informações.

Para resolver esse aviso, remova todas as funções de tipo.

Exemplo

O exemplo a seguir produz 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
}

O exemplo a seguir é um arquivo de cabeçalho que declare dois tipos. O tipo de Unsafe não estiver seguro porque tem uma função de 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;
};

Este exemplo exporta funções com tipos definidos no arquivo de cabeçalho.

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

A convenção padrão de chamada em uma compilação de /clr:pure é diferente de uma compilação nativo. Quando C4412.h for incluído, Test padrão será a __clrcall. Se você compila e executa esse programa (não use /c), o programa gerará uma exceção.

O exemplo a seguir produz 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
}