Partilhar via


Aviso do compilador (nível 2, desligado) C4412

«função»: a assinatura da função contém o tipo «tipo»; Os objetos C++ não são seguros para passar entre código puro e misto ou nativo.

Observações

A /clr:pure opção de compilador foi preterida no Visual Studio 2015 e não tem suporte a partir do Visual Studio 2017. Se você tiver um código que precisa ser CLR puro, recomendamos que você o porte para C#.

O compilador detetou uma situação potencialmente insegura que poderia resultar num erro em tempo de execução: uma chamada está a ser feita a partir de código compilado com /clr:pure para uma função importada via dllimport, e a assinatura da função contém um tipo inseguro. Um tipo não é seguro se contiver uma função de membro ou tiver um membro de dados que seja um tipo não seguro ou um indirecionamento para um tipo não seguro.

Esse padrão não é seguro devido à diferença nas convenções de chamada padrão entre código puro e nativo (ou misto nativo e gerenciado). Ao importar uma função via dllimport para código compilado com /clr:pure, certifique-se de que as declarações de cada tipo na assinatura sejam idênticas à assinatura no compilando que exporta a função (sendo especialmente cuidadoso com as diferenças nas convenções de chamada implícitas).

Uma função de membro virtual é especialmente propensa a dar resultados inesperados. No entanto, mesmo uma função não virtual deve ser testada para garantir que você obtenha os resultados corretos. Esse aviso pode ser ignorado uma vez que garantires que o resultado está correto.

C4412 está desativado por padrão. Para obter mais informações, consulte Avisos do compilador que estão desativados por padrão e dllexport, dllimport.

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

Examples

O exemplo a seguir gera C4412:

// 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 declara dois tipos. O Unsafe tipo não é 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 os 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 de chamada padrão em uma /clr:pure compilação é diferente de uma compilação nativa. Quando C4412.h estiver incluído, Test o padrão será __clrcall.

O exemplo a seguir gera C4412 e lança uma exceção em tempo de execução:

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