.NET Native dan kompilasi

Windows aplikasi desktop yang menargetkan .NET Framework ditulis dalam bahasa pemrograman tertentu dan dikompilasi ke dalam bahasa perantara (IL). Pada saat berjalan, kompiler just-in-time (JIT) bertanggung jawab untuk menyusun IL ke dalam kode asli untuk mesin lokal tepat sebelum metode dijalankan untuk pertama kalinya. Sebaliknya, rantai alat .NET Native mengubah 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 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 binari asli

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

  • Metadata yang menjelaskan perakitan, dependensinya, jenis yang dikandungnya, dan anggotanya. Metadata digunakan untuk refleksi dan akses yang terlambat, dan dalam beberapa kasus oleh compiler dan membangun alat juga.

  • Kode implementasi. Ini terdiri dari opcode bahasa menengah (IL). Saat runtime, kompiler just-in-time (JIT) menerjemahkannya ke dalam kode asli untuk platform target.

Selain perakitan aplikasi utama, aplikasi mengharuskan yang berikut ini ada:

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

  • Perpustakaan Kelas .NET Framework. Ini adalah kumpulan rakitan yang dipasang pada sistem lokal dengan instalasi .NET Framework. Rakitan yang termasuk dalam .NET Framework Class Library mencakup satu set lengkap metadata 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, remoting, dan interop. Seperti pustaka kelas, runtime diinstal pada sistem lokal sebagai bagian dari instalasi .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 dapat dijalankan dengan sukses.

Kompilasi tepat waktu

Input untuk rantai alat .NET Native adalah aplikasi UWP yang dibangun oleh kompiler C # atau Visual Basic. Dengan kata lain, rantai alat .NET Native memulai eksekusi ketika kompiler bahasa telah menyelesaikan 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. Obfuscator adalah alat yang paling terkenal dari jenis ini.

Dalam proses konversi aplikasi dari IL ke kode asli, rantai alat .NET Native melakukan operasi seperti berikut:

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

  • Jika memungkinkan, ia mencoba untuk menghilangkan semua metadata.

  • Ini termasuk dalam rakitan aplikasi akhir hanya kode implementasi yang benar-benar dipanggil oleh aplikasi. Hal ini terutama mempengaruhi kode di perpustakaan pihak ketiga dan di Perpustakaan Kelas .NET Framework. Akibatnya, aplikasi tidak lagi bergantung pada pustaka pihak ketiga atau Perpustakaan Kelas .NET Framework penuh; sebagai gantinya, kode di pustaka kelas pihak ketiga dan .NET Framework sekarang bersifat lokal ke aplikasi.

  • Ini menggantikan CLR penuh dengan runtime refactored yang terutama berisi pengumpul sampah. Runtime refactored ditemukan di perpustakaan bernama mrt100_app.dll yang bersifat lokal untuk aplikasi dan ukurannya hanya beberapa ratus kilobyte. Hal 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 perakitan yang berisi perpustakaan kelas ke kode asli sehingga dapat dipanggil secara independen dari kode terkelola.

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

  • <appName>.exe, sebuah rintisan 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 Perpustakaan Kelas .NET Framework dan pustaka pihak ketiga mana pun yang anda miliki ketergantungannya. Ini juga berisi kode dukungan, seperti kode yang diperlukan untuk beroperasi dengan Windows dan untuk membuat serial objek di aplikasi Anda.

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

Semua dependensi ditangkap 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 C run-time (CRT) yang digunakan oleh mrt100_app.dll. Ini disertakan oleh referensi kerangka kerja dalam paket.

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

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

  • Refleksi.

  • Pemanggilan dinamis atau terlambat terikat.

  • Serialisasi dan deserialisasi.

  • COM interop.

Jika metadata atau kode implementasi yang diperlukan tidak ada saat runtime, runtime .NET Native 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 saat runtime dan menetapkan kebijakan runtime kepada mereka. Berikut ini adalah file direktif 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 anggotanya, di semua rakitan dalam paket aplikasi Anda untuk refleksi dan pemanggilan dinamis. Namun, itu tidak memungkinkan refleksi atau aktivasi dinamis jenis di .NET Framework rakitan Perpustakaan Kelas. Dalam banyak kasus, ini sudah memadai.

Lihat juga