Partager via


Avertissement du compilateur (niveau 2) C4412

'function' : la signature de fonction contient le type 'type' ; Les objets C++ ne sont pas sécurisés pour passer entre du code pur et du code mixte ou natif.

Notes

L’option /clr :pure compiler est déconseillée dans Visual Studio 2015 et non prise en charge dans Visual Studio 2017. Si vous avez du code qui doit être pur, nous vous recommandons de le porter vers C#.

Le compilateur a détecté une situation potentiellement dangereuse qui pourrait entraîner une erreur d’exécution : un appel est effectué à partir d’une compilation /clr :pure vers une fonction importée via dllimport et la signature de la fonction contient un type non sécurisé. Un type est dangereux s’il contient une fonction membre ou a un membre de données qui est un type non sécurisé ou un indirection à un type non sécurisé.

Cela est dangereux en raison de la différence entre les conventions d’appel par défaut entre le code pur et natif (ou le code natif mixte et managé). Lors de l’importation (via dllimport) d’une fonction dans une compilation /clr :pure , assurez-vous que les déclarations de chaque type dans la signature sont identiques à celles de la compilation qui exporte la fonction (étant particulièrement prudent sur les différences dans les conventions d’appel implicites).

Une fonction membre virtuelle est particulièrement sujette à des résultats inattendus. Toutefois, même une fonction non virtuelle doit être testée pour vous assurer que vous obtenez les résultats corrects. Si vous êtes sûr que vous obtenez les résultats corrects, vous pouvez ignorer cet avertissement.

C4412 est désactivé par défaut. Pour plus d’informations, consultez avertissements du compilateur désactivés par défaut et dllexport .

Pour résoudre cet avertissement, supprimez toutes les fonctions du type.

Exemples

L’exemple suivant génère l’erreur 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’exemple suivant est un fichier d’en-tête qui déclare deux types. Le Unsafe type est dangereux, car il a une fonction membre.

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

Cet exemple exporte des fonctions avec les types définis dans le fichier d’en-tête.

// 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 convention d’appel par défaut dans une compilation /clr :pure est différente d’une compilation native. Lorsque C4412.h est inclus, Test la __clrcallvaleur par défaut est . Si vous compilez et exécutez ce programme (n’utilisez pas /c), le programme lève une exception.

L’exemple suivant génère l’erreur 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
}