Jenis Terkelola (C++/CLI)
Visual C++ memungkinkan akses ke fitur .NET melalui jenis terkelola, yang menyediakan dukungan untuk fitur runtime bahasa umum dan tunduk pada keuntungan dan batasan runtime.
Jenis Terkelola dan Fungsi utama
Saat Anda menulis aplikasi menggunakan /clr
, argumen main()
fungsi tidak boleh dari jenis terkelola.
Contoh tanda tangan yang tepat adalah:
// managed_types_and_main.cpp
// compile with: /clr
int main(int, char*[], char*[]) {}
.NET Framework Setara dengan Jenis Asli C++
Tabel berikut ini memperlihatkan kata kunci untuk jenis Visual C++ bawaan, yang merupakan alias dari jenis yang telah ditentukan sebelumnya di namespace layanan Sistem .
Jenis Visual C++ | Jenis .NET Framework |
---|---|
void |
System.Void |
bool |
System.Boolean |
signed char |
System.SByte |
unsigned char |
System.Byte |
wchar_t |
System.Char |
short dan signed short |
System.Int16 |
unsigned short |
System.UInt16 |
int , signed int , long , dan signed long |
System.Int32 |
unsigned int dan unsigned long |
System.UInt32 |
__int64 dan signed __int64 |
System.Int64 |
unsigned __int64 |
System.UInt64 |
float |
System.Single |
double dan long double |
System.Double |
Untuk informasi selengkapnya tentang opsi pengkompilasi ke default ke signed char
atau unsigned char
, lihat /J
(Jenis default char
adalah unsigned
).
Masalah Versi untuk Jenis Nilai yang Disarangkan dalam Jenis Asli
Pertimbangkan komponen rakitan yang ditandatangani (nama kuat) yang digunakan untuk membangun rakitan klien. Komponen berisi jenis nilai yang digunakan dalam klien sebagai jenis untuk anggota serikat asli, kelas, atau array. Jika versi komponen yang akan datang mengubah ukuran atau tata letak jenis nilai, klien harus dikompresi ulang.
Buat keyfile dengan sn.exe (sn -k mykey.snk
).
Contoh
Sampel berikut adalah komponennya.
// nested_value_types.cpp
// compile with: /clr /LD
using namespace System::Reflection;
[assembly:AssemblyVersion("1.0.0.*"),
assembly:AssemblyKeyFile("mykey.snk")];
public value struct S {
int i;
void Test() {
System::Console::WriteLine("S.i = {0}", i);
}
};
Sampel ini adalah klien:
// nested_value_types_2.cpp
// compile with: /clr
#using <nested_value_types.dll>
struct S2 {
S MyS1, MyS2;
};
int main() {
S2 MyS2a, MyS2b;
MyS2a.MyS1.i = 5;
MyS2a.MyS2.i = 6;
MyS2b.MyS1.i = 10;
MyS2b.MyS2.i = 11;
MyS2a.MyS1.Test();
MyS2a.MyS2.Test();
MyS2b.MyS1.Test();
MyS2b.MyS2.Test();
}
Contoh menghasilkan output ini:
S.i = 5
S.i = 6
S.i = 10
S.i = 11
Komentar
Namun, jika Anda menambahkan anggota lain ke struct S
dalam nested_value_types.cpp
(misalnya, double d;
) dan mengkompilasi ulang komponen tanpa juga mengkompilasi ulang klien, hasilnya adalah pengecualian yang tidak tertangani (dari jenis System.IO.FileLoadException).
Cara menguji kesetaraan
Dalam sampel berikut, pengujian untuk kesetaraan yang menggunakan Ekstensi Terkelola untuk C++ didasarkan pada apa yang dirujuk oleh handel.
Contoh
// mcppv2_equality_test.cpp
// compile with: /clr /LD
using namespace System;
bool Test1() {
String ^ str1 = "test";
String ^ str2 = "test";
return (str1 == str2);
}
IL untuk program ini menunjukkan bahwa nilai pengembalian diimplementasikan dengan menggunakan panggilan ke op_Equality
.
IL_0012: call bool [mscorlib]System.String::op_Equality(string, string)
Cara mendiagnosis dan memperbaiki masalah kompatibilitas perakitan
Ketika versi rakitan yang dirujuk pada waktu kompilasi tidak cocok dengan versi rakitan yang dirujuk saat runtime, berbagai masalah dapat terjadi.
Ketika rakitan dikompilasi, rakitan lain dapat dirujuk dengan #using
sintaks. Selama kompilasi, rakitan ini diakses oleh pengkompilasi. Informasi dari rakitan ini digunakan untuk membuat keputusan pengoptimalan.
Namun, jika rakitan yang direferensikan diubah dan dikombinasikan ulang, juga kompilasi ulang rakitan referensi yang bergantung padanya. Jika tidak, rakitan mungkin menjadi tidak kompatibel. Keputusan pengoptimalan yang valid pada awalnya mungkin tidak benar untuk versi rakitan baru. Berbagai kesalahan runtime mungkin terjadi karena ketidaksesuaian ini. Tidak ada pengecualian khusus yang dihasilkan dalam kasus seperti itu. Cara kegagalan dilaporkan pada runtime tergantung pada sifat perubahan kode yang menyebabkan masalah.
Kesalahan ini seharusnya tidak menjadi masalah dalam kode produksi akhir Anda selama seluruh aplikasi dibangun kembali untuk versi produk Anda yang dirilis. Rakitan yang dirilis ke publik harus ditandai dengan nomor versi resmi, yang akan memastikan bahwa masalah ini dihindari. Untuk informasi selengkapnya, lihat Penerapan Versi Rakitan.
Untuk mendiagnosis dan memperbaiki kesalahan ketidaksesuaian
Anda mungkin mengalami pengecualian runtime atau kondisi kesalahan lainnya dalam kode yang mereferensikan rakitan lain. Jika Anda tidak dapat mengidentifikasi penyebab lain, masalahnya mungkin merupakan rakitan yang sudah kedaluarsa.
Pertama, isolasi dan reproduksi pengecualian atau kondisi kesalahan lainnya. Masalah yang terjadi karena pengecualian yang kedaluarsa harus dapat direproduksi.
Periksa tanda waktu rakitan apa pun yang dirujuk dalam aplikasi Anda.
Jika tanda waktu dari rakitan yang dirujuk lebih lambat dari tanda waktu kompilasi terakhir aplikasi Anda, maka aplikasi Anda kedaluarsa. Jika sudah kedaluarsa, kompilasi ulang aplikasi Anda dengan rakitan terbaru, dan edit kode Anda jika perlu.
Jalankan ulang aplikasi, lakukan langkah-langkah yang mereproduksi masalah, dan verifikasi bahwa pengecualian tidak terjadi.
Contoh
Program berikut mengilustrasikan masalah: pertama-tama mengurangi aksesibilitas metode, lalu mencoba mengakses metode tersebut di rakitan lain tanpa kompilasi ulang. Kompilasi changeaccess.cpp
terlebih dahulu. Ini adalah rakitan yang dirujuk yang akan berubah. Kemudian kompilasi referencing.cpp
. Ini harus berhasil dikompilasi. Selanjutnya, kurangi aksesibilitas metode yang disebut. Kompilasi ulang changeaccess.cpp
dengan opsi /DCHANGE_ACCESS
pengkompilasi . Ini membuat access_me
metode , bukan public
, sehingga tidak dapat dipanggil dari luar Test
atau protected
turunannya. Tanpa mengolah referencing.exe
ulang , jalankan ulang aplikasi. Terjadi MethodAccessException .
// changeaccess.cpp
// compile with: /clr:safe /LD
// After the initial compilation, add /DCHANGE_ACCESS and rerun
// referencing.exe to introduce an error at runtime. To correct
// the problem, recompile referencing.exe
public ref class Test {
#if defined(CHANGE_ACCESS)
protected:
#else
public:
#endif
int access_me() {
return 0;
}
};
Berikut adalah sumber untuk rakitan referensi:
// referencing.cpp
// compile with: /clr:safe
#using <changeaccess.dll>
// Force the function to be inline, to override the compiler's own
// algorithm.
__forceinline
int CallMethod(Test^ t) {
// The call is allowed only if access_me is declared public
return t->access_me();
}
int main() {
Test^ t = gcnew Test();
try
{
CallMethod(t);
System::Console::WriteLine("No exception.");
}
catch (System::Exception ^ e)
{
System::Console::WriteLine("Exception!");
}
return 0;
}
Lihat juga
Pemrograman .NET dengan C++/CLI (Visual C++)
Interoperabilitas dengan bahasa .NET lainnya (C++/CLI)
Jenis terkelola (C++/CLI)
#using
Direktif