Bagikan melalui


Compiler Warning (level 2) C4412

'function' : tanda tangan fungsi berisi tipe 'type'; Objek C++ tidak aman untuk diteruskan antara kode murni dan campuran atau asli.

Keterangan

Opsi kompilator /clr:pure tidak digunakan lagi di Visual Studio 2015 dan tidak didukung di Visual Studio 2017. Jika Anda memiliki kode yang perlu murni, kami sarankan Anda memindahkannya ke C#.

Kompilator mendeteksi situasi yang berpotensi tidak aman yang dapat mengakibatkan kesalahan runtime: panggilan sedang dilakukan dari kompilasi /clr:pure ke fungsi yang diimpor melalui dllimport dan tanda tangan fungsi berisi jenis yang tidak aman. Jenis tidak aman jika berisi fungsi anggota atau memiliki anggota data yang merupakan jenis tidak aman atau tidak langsung ke jenis yang tidak aman.

Ini tidak aman karena perbedaan dalam konvensi panggilan default antara kode murni dan asli (atau campuran asli dan terkelola). Saat mengimpor (melalui dllimport) fungsi ke dalam kompilasi /clr:pure , pastikan bahwa deklarasi setiap jenis dalam tanda tangan identik dengan fungsi di kompilasi yang mengekspor fungsi (sangat berhati-hati tentang perbedaan dalam konvensi panggilan implisit).

Fungsi anggota virtual sangat rentan untuk memberikan hasil yang tidak terduga. Namun, bahkan fungsi non-virtual harus diuji untuk memastikan bahwa Anda mendapatkan hasil yang benar. Jika Anda yakin bahwa Anda mendapatkan hasil yang benar, Anda dapat mengabaikan peringatan ini.

C4412 nonaktif secara default. Lihat Peringatan Pengkompilasi yang Nonaktif secara Default dan dllexport, dllimport untuk informasi selengkapnya.

Untuk mengatasi peringatan ini, hapus semua fungsi dari jenis .

Contoh

Sampel berikut menghasilkan 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
}

Sampel berikut adalah file header yang mendeklarasikan dua jenis. Jenis Unsafe tidak aman karena memiliki fungsi anggota.

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

Sampel ini mengekspor fungsi dengan jenis yang ditentukan dalam file header.

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

Konvensi panggilan default dalam kompilasi /clr:pure berbeda dari kompilasi asli. Ketika C4412.h disertakan, Test default ke __clrcall. Jika Anda mengkompilasi dan menjalankan program ini (jangan gunakan /c), program akan memunculkan pengecualian.

Sampel berikut menghasilkan 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
}