Komponen Windows Runtime dengan C++/WinRT

Topik ini menunjukkan cara menggunakan C++/WinRT untuk membuat dan menggunakan komponen Windows Runtime—komponen yang dapat dipanggil dari aplikasi Universal Windows yang dibuat menggunakan bahasa Windows Runtime apa pun.

Ada beberapa alasan untuk membangun komponen Windows Runtime di C++/WinRT.

  • Untuk menikmati keuntungan performa C++ dalam operasi yang kompleks atau intensif secara komputasi.
  • Untuk menggunakan kembali kode C++ standar yang sudah ditulis dan diuji.
  • Untuk mengekspos fungsionalitas Win32 ke aplikasi Platform Windows Universal (UWP) yang ditulis, misalnya, C#.

Secara umum, ketika Anda menulis komponen C++/WinRT, Anda dapat menggunakan jenis dari pustaka C++ standar, dan jenis bawaan, kecuali pada batas antarmuka biner aplikasi (ABI) tempat Anda meneruskan data ke dan dari kode dalam paket lain .winmd . Di ABI, gunakan jenis Windows Runtime. Selain itu, dalam kode C++/WinRT Anda, gunakan jenis seperti delegasi dan peristiwa untuk mengimplementasikan peristiwa yang dapat dinaikkan dari komponen Anda dan ditangani dalam bahasa lain. Lihat C++/WinRT untuk informasi selengkapnya tentang C++/WinRT.

Sisa topik ini memanmbing Anda melalui cara menulis komponen Windows Runtime di C++/WinRT, lalu cara menggunakannya dari aplikasi.

Komponen Windows Runtime yang akan Anda bangun dalam topik ini berisi kelas runtime yang mewakili termometer. Topik ini juga menunjukkan Aplikasi Inti yang menggunakan kelas runtime termometer, dan memanggil fungsi untuk menyesuaikan suhu.

Catatan

Untuk informasi tentang menginstal dan menggunakan C++/WinRT Visual Studio Extension (VSIX) dan paket NuGet (yang bersama-sama menyediakan templat proyek dan dukungan build), lihat Dukungan Visual Studio untuk C++/WinRT.

Penting

Untuk konsep dan istilah penting yang mendukung pemahaman Anda tentang cara menggunakan dan menulis kelas runtime dengan C++/WinRT, lihat Menggunakan API dengan C++/WinRT dan API Penulis dengan C++/WinRT.

Praktik terbaik penamaan untuk dll komponen Windows Runtime

Penting

Bagian ini menjelaskan konvensi penamaan yang kami sarankan Anda gunakan untuk .dll file (DLL) tempat Anda membangun komponen Windows Runtime. Ini semua tentang urutan aktivasi yang diikuti C++/WinRT saat Anda menggunakan kelas runtime dari komponen Windows Runtime.

Saat mengaktifkan pabrik kelas, C++/WinRT terlebih dahulu mencoba panggilan ke RoGetActivationFactory. Jika gagal, C++/WinRT mencoba menemukan DLL untuk dimuat secara langsung. Aktivasi Windows Runtime selalu didasarkan pada nama kelas yang sepenuhnya memenuhi syarat. Logikanya adalah menghapus nama kelas (dari nama kelas yang sepenuhnya memenuhi syarat), lalu mencari DLL bernama untuk namespace lengkap yang tersisa. Jika tidak ditemukan, hapus nama segmen yang paling spesifik, dan ulangi.

Jadi misalnya jika kelas yang diaktifkan memiliki nama Contoso.Instruments.ThermometerWRC.Thermometer yang sepenuhnya memenuhi syarat, dan RoGetActivationFactory gagal, maka pertama-tama kita akan mencari Contoso.Instruments.ThermometerWRC.dll. Jika itu tidak ditemukan, maka kita akan mencari Contoso.Instruments.dll, dan kemudian untuk Contoso.dll.

Ketika DLL ditemukan (dalam urutan itu), kita akan menggunakan titik entri DllGetActivationFactory DLL itu untuk mencoba mendapatkan pabrik secara langsung (daripada secara tidak langsung melalui fungsi RoGetActivationFactory yang pertama kali kita coba). Meskipun demikian, hasil akhirnya tidak dapat dibedakan oleh pemanggil dan ke DLL.

Proses ini sepenuhnya otomatis—tidak diperlukan pendaftaran atau alat. Jika Anda menulis komponen Windows Runtime, maka Anda hanya perlu menggunakan konvensi penamaan untuk DLL Anda yang berfungsi dengan proses yang baru saja dijelaskan. Dan jika Anda menggunakan komponen Windows Runtime dan tidak dinamai dengan benar, maka Anda memiliki opsi untuk mengganti namanya seperti yang dijelaskan.

Membuat komponen Windows Runtime (ThermometerWRC)

Mulailah dengan membuat proyek baru di Microsoft Visual Studio. Buat proyek Windows Runtime Component (C++/WinRT), dan beri nama ThermometerWRC (untuk "komponen termometer Windows Runtime"). Pastikan bahwa Tempatkan solusi dan proyek di direktori yang sama tidak dicentang. Targetkan versi terbaru yang tersedia secara umum (yaitu, bukan pratinjau) dari Windows SDK. Penamaan proyek ThermometerWRC akan memberi Anda pengalaman termampu dengan langkah-langkah lain dalam topik ini.

Jangan membangun proyek belum.

Proyek yang baru dibuat berisi file bernama Class.idl. Di Penjelajah Solusi, ganti nama file Thermometer.idl tersebut .idl (mengganti nama file secara otomatis mengganti nama dependen .h dan .cpp file juga). Ganti isi Thermometer.idl dengan daftar di bawah ini.

// Thermometer.idl
namespace ThermometerWRC
{
    runtimeclass Thermometer
    {
        Thermometer();
        void AdjustTemperature(Single deltaFahrenheit);
    };
}

Simpan file. Proyek ini tidak akan dibangun hingga selesai saat ini, tetapi membangun sekarang adalah hal yang berguna untuk dilakukan karena menghasilkan file kode sumber tempat Anda akan mengimplementasikan kelas runtime Thermometer . Jadi lanjutkan dan bangun sekarang (kesalahan build yang dapat Anda harapkan untuk dilihat pada tahap ini ada hubungannya dengan Class.h dan Class.g.h tidak ditemukan).

Selama proses build, midl.exe alat ini dijalankan untuk membuat file metadata Windows Runtime komponen Anda (yaitu \ThermometerWRC\Debug\ThermometerWRC\ThermometerWRC.winmd). Kemudian, cppwinrt.exe alat ini dijalankan (dengan -component opsi ) untuk menghasilkan file kode sumber untuk mendukung Anda dalam menulis komponen Anda. File-file ini termasuk stub untuk membuat Anda mulai menerapkan kelas runtime Thermometer yang Anda deklarasikan di IDL Anda. Mereka ganja adalah \ThermometerWRC\ThermometerWRC\Generated Files\sources\Thermometer.h dan Thermometer.cpp.

Klik kanan simpul proyek dan klik Buka Folder di File Explorer. Ini membuka folder proyek di File Explorer. Di sana, salin file Thermometer.h stub dan Thermometer.cpp dari folder \ThermometerWRC\ThermometerWRC\Generated Files\sources\ dan ke folder yang berisi file proyek Anda, yaitu \ThermometerWRC\ThermometerWRC\, dan ganti file di tujuan. Sekarang, mari kita buka Thermometer.h dan Thermometer.cpp dan terapkan kelas runtime kita. Dalam Thermometer.h, tambahkan anggota swasta baru ke implementasi (bukan implementasi pabrik) Thermometer.

// Thermometer.h
...
namespace winrt::ThermometerWRC::implementation
{
    struct Thermometer : ThermometerT<Thermometer>
    {
        ...

    private:
        float m_temperatureFahrenheit { 0.f };
    };
}
...

Dalam Thermometer.cpp, terapkan metode AdjustTemperature seperti yang ditunjukkan pada daftar di bawah ini.

// Thermometer.cpp
...
namespace winrt::ThermometerWRC::implementation
{
    void Thermometer::AdjustTemperature(float deltaFahrenheit)
    {
        m_temperatureFahrenheit += deltaFahrenheit;
    }
}

Anda akan melihat static_assert di bagian Thermometer.h atas dan Thermometer.cpp, yang harus Anda hapus. Sekarang proyek akan dibangun.

Jika ada peringatan yang mencegah Anda membangun, selesaikan atau atur properti proyek C/C++>General>Treat Warnings Sebagai Kesalahan ke Tidak (/WX-),dan buat proyek lagi.

Membuat Aplikasi Inti (ThermometerCoreApp) untuk menguji komponen Windows Runtime

Sekarang buat proyek baru (baik di solusi ThermometerWRC Anda, atau yang baru). Buat proyek Aplikasi Inti (C++/WinRT), dan beri nama ThermometerCoreApp. Atur ThermometerCoreApp sebagai proyek startup jika kedua proyek berada dalam solusi yang sama.

Catatan

Seperti disebutkan sebelumnya, file metadata Windows Runtime untuk komponen Windows Runtime Anda (yang proyeknya Anda beri nama ThermometerWRC) dibuat di folder \ThermometerWRC\Debug\ThermometerWRC\. Segmen pertama dari jalur tersebut adalah nama folder yang berisi file solusi Anda; segmen berikutnya adalah subdirektori yang bernama Debug; dan segmen terakhir adalah subdirektori yang dinamai untuk komponen Windows Runtime Anda. Jika Anda tidak memberi nama proyek Anda ThermometerWRC, maka file metadata Anda akan berada di folder \<YourProjectName>\Debug\<YourProjectName>\.

Sekarang, dalam proyek Aplikasi Inti Anda (ThermometerCoreApp), tambahkan referensi, dan telusuri \ThermometerWRC\Debug\ThermometerWRC\ThermometerWRC.winmd (atau tambahkan referensi proyek-ke-proyek, jika kedua proyek berada dalam solusi yang sama). Klik Tambahkan, lalu OK. Sekarang bangun ThermometerCoreApp. Jika Anda melihat kesalahan bahwa file readme.txt payload tidak ada, kecualikan file tersebut dari proyek komponen Windows Runtime, bangun kembali, lalu bangun kembali ThermometerCoreApp.

Selama proses build, cppwinrt.exe alat ini dijalankan untuk memproses file yang direferensikan .winmd ke dalam file kode sumber yang berisi jenis yang diproyeksikan untuk mendukung Anda dalam mengonsumsi komponen Anda. Header untuk jenis yang diproyeksikan untuk kelas runtime komponen Anda—bernama ThermometerWRC.h—dihasilkan ke dalam folder \ThermometerCoreApp\ThermometerCoreApp\Generated Files\winrt\.

Sertakan header tersebut di App.cpp.

// App.cpp
...
#include <winrt/ThermometerWRC.h>
...

Juga dalam , tambahkan kode berikut untuk membuat instans objek Termometer (menggunakan konstruktor default jenis yang diproyeksikanApp.cpp), dan panggil metode pada objek termometer.

struct App : implements<App, IFrameworkViewSource, IFrameworkView>
{
    ThermometerWRC::Thermometer m_thermometer;
    ...
    
    void OnPointerPressed(IInspectable const &, PointerEventArgs const & args)
    {
        m_thermometer.AdjustTemperature(1.f);
        ...
    }
    ...
};

Setiap kali Anda mengklik jendela, Anda menaikkan suhu objek termometer. Anda dapat mengatur titik henti jika Anda ingin menelusuri kode untuk mengonfirmasi bahwa aplikasi benar-benar memanggil komponen Windows Runtime.

Langkah berikutnya

Untuk menambahkan lebih banyak fungsionalitas, atau jenis Windows Runtime baru, ke komponen C++/WinRT Windows Runtime Anda, Anda dapat mengikuti pola yang sama seperti yang ditunjukkan di atas. Pertama, gunakan IDL untuk menentukan fungsionalitas yang ingin Anda ekspos. Kemudian buat proyek di Visual Studio untuk menghasilkan implementasi stub. Dan kemudian selesaikan implementasi yang sesuai. Metode, properti, dan peristiwa apa pun yang Anda tentukan di IDL terlihat oleh aplikasi yang menggunakan Komponen Runtime Windows Anda. Untuk informasi selengkapnya tentang IDL, lihat Pengenalan Microsoft Interface Definition Language 3.0.

Untuk contoh cara menambahkan peristiwa ke Komponen Runtime Windows Anda, lihat Menulis peristiwa di C++/WinRT.

Pemecahan Masalah

Gejala Obat
Dalam aplikasi C++/WinRT, saat menggunakan komponen C# Windows Runtime yang menggunakan XAML, pengkompilasi menghasilkan kesalahan formulir "'MyNamespace_XamlTypeInfo': bukan anggota 'winrt::MyNamespace'"—di mana MyNamespace adalah nama namespace komponen Windows Runtime. Di pch.h aplikasi C++/WinRT yang mengkonsumsi, tambahkan #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>—mengganti MyNamespace sebagaimana mestinya.