Bagikan melalui


.NET Native dan kompilasi

Aplikasi desktop Windows yang menargetkan .NET Framework ditulis dalam bahasa pemrograman tertentu dan dikompilasi ke dalam bahasa perantara (IL). Pada waktu proses, kompilator just-in-time (JIT) bertanggung jawab untuk mengkompilasi IL ke dalam kode asli untuk komputer lokal tepat sebelum metode dijalankan untuk pertama kalinya. Sebaliknya, rantai alat .NET Native mengonversi kode sumber menjadi kode asli pada waktu kompilasi. Artikel ini membandingkan .NET Native dengan teknologi kompilasi lain yang tersedia untuk aplikasi .NET Framework, dan juga memberikan gambaran umum praktis tentang bagaimana .NET Native menghasilkan kode asli yang dapat membantu Anda memahami mengapa pengecualian yang terjadi dalam kode yang dikompilasi dengan .NET Native tidak terjadi dalam kode yang dikompilasi JIT.

Menghasilkan biner asli

Aplikasi yang menargetkan .NET Framework dan yang tidak dikompilasi dengan menggunakan rantai alat .NET Native terdiri dari rakitan aplikasi, yang mencakup hal berikut:

  • Metadata yang menjelaskan rakitan, dependensinya, jenis yang dikandungnya, dan anggotanya. Metadata digunakan untuk refleksi dan akses yang terlambat terikat, dan dalam beberapa kasus dengan mengkompilasi dan membangun alat juga.

  • Kode implementasi. Ini terdiri dari opkode bahasa perantara (IL). Pada runtime, kompilator just-in-time (JIT) menerjemahkannya ke dalam kode asli untuk platform target.

Selain perakitan aplikasi utama, aplikasi mengharuskan adanya hal berikut:

  • Pustaka kelas tambahan atau rakitan pihak ketiga apa pun yang diperlukan oleh aplikasi Anda. Rakitan ini juga mencakup metadata yang menjelaskan perakitan, jenisnya, dan anggotanya, serta IL yang mengimplementasikan semua anggota jenis.

  • Pustaka Kelas .NET Framework. Ini adalah kumpulan rakitan yang diinstal pada sistem lokal dengan penginstalan .NET Framework. Rakitan yang disertakan dalam Pustaka Kelas .NET Framework menyertakan serangkaian metadata lengkap dan kode implementasi.

  • Runtime bahasa umum. Ini adalah kumpulan pustaka tautan dinamis yang melakukan layanan seperti pemuatan perakitan, manajemen memori dan pengumpulan sampah, penanganan pengecualian, kompilasi just-in-time, jarak jauh, dan interop. Seperti pustaka kelas, runtime diinstal pada sistem lokal sebagai bagian dari penginstalan .NET Framework.

Perhatikan bahwa seluruh runtime bahasa umum, serta metadata dan IL untuk semua jenis dalam rakitan khusus aplikasi, rakitan pihak ketiga, dan rakitan sistem harus ada agar aplikasi berhasil dijalankan.

Kompilasi just-in-time

Input untuk rantai alat .NET Native adalah aplikasi UWP yang dibangun oleh pengkompilasi C# atau Visual Basic. Dengan kata lain, rantai alat .NET Native memulai eksekusi ketika pengkompilasi bahasa telah selesai kompilasi aplikasi UWP.

Tip

Karena input ke .NET Native adalah IL dan metadata yang ditulis ke rakitan terkelola, Anda masih dapat melakukan pembuatan kode kustom atau operasi kustom lainnya dengan menggunakan peristiwa pra-build atau pasca-build atau dengan memodifikasi file proyek MSBuild.

Namun, kategori alat yang memodifikasi IL dan dengan demikian mencegah rantai alat .NET menganalisis IL aplikasi tidak didukung. Obfuscators adalah alat paling terkenal dari jenis ini.

Selama mengonversi aplikasi dari IL ke kode asli, rantai alat .NET Native melakukan operasi seperti berikut:

  • Untuk jalur kode tertentu, ini menggantikan kode yang bergantung pada pantulan dan metadata dengan kode asli statis. Misalnya, jika jenis nilai tidak mengambil alih ValueType.Equals metode , pengujian default untuk kesetaraan menggunakan pantulan untuk mengambil FieldInfo objek yang mewakili bidang jenis nilai, lalu membandingkan nilai bidang dari dua instans. Saat mengkompilasi ke kode asli, rantai alat .NET Native menggantikan kode pantulan dan metadata dengan perbandingan statis dari nilai bidang.

  • Jika memungkinkan, ia mencoba menghilangkan semua metadata.

  • Ini termasuk dalam rakitan aplikasi akhir hanya kode implementasi yang benar-benar dipanggil oleh aplikasi. Ini sangat memengaruhi kode di pustaka pihak ketiga dan di Pustaka Kelas .NET Framework. Akibatnya, aplikasi tidak lagi bergantung pada pustaka pihak ketiga atau Pustaka Kelas .NET Framework lengkap; sebagai gantinya, kode di pustaka kelas pihak ketiga dan .NET Framework sekarang lokal untuk aplikasi.

  • Ini menggantikan CLR penuh dengan runtime refaktor yang terutama berisi pengumpul sampah. Runtime yang direfaktor ditemukan di pustaka bernama mrt100_app.dll yang berukuran lokal untuk aplikasi dan hanya berukuran beberapa ratus kilobyte. Ini dimungkinkan karena penautan statis menghilangkan kebutuhan akan banyak layanan yang dilakukan oleh runtime bahasa umum.

    Catatan

    .NET Native menggunakan pengumpul sampah yang sama dengan runtime bahasa umum standar. Di pengumpul sampah .NET Native, pengumpulan sampah latar belakang diaktifkan secara default. Untuk informasi selengkapnya tentang pengumpulan sampah, lihat Dasar-Dasar Pengumpulan Sampah.

Penting

.NET Native mengkompilasi seluruh aplikasi ke aplikasi asli. Ini tidak memungkinkan Anda untuk mengkompilasi satu rakitan yang berisi pustaka kelas ke kode asli sehingga dapat dipanggil secara independen dari kode terkelola.

Aplikasi yang dihasilkan yang dihasilkan oleh rantai alat .NET Native ditulis ke direktori bernama ilc.out di direktori Debug atau Rilis direktori proyek Anda. Ini terdiri dari file-file berikut:

  • <appName>.exe, stub yang dapat dieksekusi yang hanya mentransfer kontrol ke ekspor khusus Main di <appName>.dll.

  • <appName>.dll, pustaka tautan dinamis Windows yang berisi semua kode aplikasi Anda, serta kode dari Pustaka Kelas .NET Framework dan pustaka pihak ketiga apa pun yang anda miliki dependensinya. Ini juga berisi kode dukungan, seperti kode yang diperlukan untuk beroperasi dengan Windows dan untuk menserialisasikan objek di aplikasi Anda.

  • mrt100_app.dll, runtime refaktor yang menyediakan layanan runtime seperti pengumpulan sampah.

Semua dependensi diambil oleh manifes APPX aplikasi. Selain exe aplikasi, dll, dan mrt100_app.dll, yang dibundel langsung dalam paket appx, ini termasuk dua file lagi:

  • msvcr140_app.dll, pustaka run-time C (CRT) yang digunakan oleh mrt100_app.dll. Ini disertakan oleh referensi kerangka kerja dalam paket.

  • mrt100.dll. Pustaka ini mencakup fungsi yang dapat meningkatkan performa mrt100_app.dll, meskipun ketidakhadirannya tidak mencegah mrt100_app.dll berfungsi. Ini dimuat dari direktori system32 pada komputer lokal, jika ada.

Karena rantai alat .NET Native menautkan kode implementasi ke dalam aplikasi Anda hanya jika tahu bahwa aplikasi Anda benar-benar memanggil kode tersebut, metadata atau kode implementasi yang diperlukan dalam skenario berikut mungkin tidak disertakan dengan aplikasi Anda:

  • Refleksi.

  • Pemanggilan dinamis atau terikat terlambat.

  • Serialisasi dan deserialisasi.

  • Interop COM.

Jika metadata atau kode implementasi yang diperlukan tidak ada pada runtime, runtime .NET Native akan memberikan pengecualian. Anda dapat mencegah pengecualian ini, dan memastikan bahwa rantai alat .NET Native menyertakan metadata dan kode implementasi yang diperlukan, dengan menggunakan file arahan runtime, file XML yang menunjuk elemen program yang metadata atau kode implementasinya harus tersedia pada runtime dan menetapkan kebijakan runtime kepada mereka. Berikut ini adalah file arahan runtime default yang ditambahkan ke proyek UWP yang dikompilasi oleh rantai alat .NET Native:

<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
  <Application>
    <Assembly Name="*Application*" Dynamic="Required All" />
  </Application>
</Directives>

Ini memungkinkan semua jenis, serta semua anggota mereka, di semua rakitan dalam paket aplikasi Anda untuk refleksi dan pemanggilan dinamis. Namun, ini tidak mengaktifkan refleksi atau aktivasi dinamis jenis dalam rakitan Pustaka Kelas .NET Framework. Dalam banyak kasus, ini memadai.

Lihat juga