Share via


Upozornění kompilátoru (úroveň 2) C4412

'function' : podpis funkce obsahuje typ 'type'; Objekty jazyka C++ jsou nebezpečné pro předávání mezi čistým kódem a smíšeným nebo nativním kódem.

Poznámky

Možnost /clr:pure compiler je v sadě Visual Studio 2015 zastaralá a v sadě Visual Studio 2017 není podporována. Pokud máte kód, který musí být čistý, doporučujeme ho přenést do C#.

Kompilátor zjistil potenciálně nebezpečnou situaci, která by mohla vést k chybě za běhu: volání se provádí z /clr:pure compiland na funkci, která byla importována přes dllimport a podpis funkce obsahuje nebezpečný typ. Typ je nebezpečný, pokud obsahuje členovou funkci nebo má datový člen, který je nebezpečným typem nebo nepřímým převodem na nebezpečný typ.

To je nebezpečné kvůli rozdílu ve výchozích konvencích volání mezi čistým a nativním kódem (nebo smíšeným nativním a spravovaným). Při importu (prostřednictvím dllimport) funkce do /clr:pure compiland se ujistěte, že deklarace každého typu v podpisu jsou stejné jako deklarace v kompeteně, které funkci exportují (zejména pozor na rozdíly v implicitních konvencích volání).

Virtuální členová funkce je obzvláště náchylná k tomu, aby poskytovala neočekávané výsledky. I ne-virtuální funkce by ale měla být testována, abyste měli jistotu, že získáte správné výsledky. Pokud máte jistotu, že se zobrazují správné výsledky, můžete toto upozornění ignorovat.

C4412 je ve výchozím nastavení vypnutý. Další informace naleznete v tématu Upozornění kompilátoru, které jsou ve výchozím nastavení vypnuté a dllexport, dllimport .

Pokud chcete toto upozornění vyřešit, odeberte z typu všechny funkce.

Příklady

Následující ukázka vygeneruje 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
}

Následující ukázka je soubor hlaviček, který deklaruje dva typy. Typ Unsafe je nebezpečný, protože má členovou funkci.

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

Tato ukázka exportuje funkce s typy definovanými v souboru hlaviček.

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

Výchozí konvence volání v kompilaci /clr:pure se liší od nativní kompilace. Pokud je součástí C4412.h, Test použije se __clrcallvýchozí hodnota . Pokud tento program zkompilujete a spustíte (nepoužívejte /c), program vyvolá výjimku.

Následující ukázka vygeneruje 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
}