Cara: Menggunakan kode C++ yang ada di aplikasi Universelle Windows-Plattform

Ada berbagai cara agar Anda dapat menggunakan kode C ++ yang ada di proyek Universelle Windows-Plattform (UWP). Beberapa cara tidak memerlukan kode untuk dikompilasi ulang dengan ekstensi komponen (C ++/CX) diaktifkan (yaitu, dengan /ZW opsi), dan beberapa melakukannya. Anda mungkin perlu menyimpan kode dalam C ++standar, atau mempertahankan lingkungan kompilasi Win32 klasik untuk beberapa kode. Anda masih dapat melakukannya, dengan pilihan arsitektur yang tepat. Pertimbangkan semua kode Anda yang berisi UI UWP dan jenis yang terpapar pemanggil C#, Visual Basic, dan JavaScript. Kode ini harus berada dalam proyek Aplikasi Windows dan proyek Komponen Windows 运行时. Kode yang hanya Anda panggil dari C ++ (termasuk C ++/CX) dapat berada dalam proyek yang dikompilasi /ZW dengan opsi atau proyek C ++ standar. Kode biner saja yang tidak menggunakan API yang tidak diizinkan dapat digunakan dengan menautkannya sebagai pustaka statis. Atau, Anda dapat mengemasnya dengan aplikasi sebagai konten dan memuatnya dalam DLL.

Mungkin cara termudah untuk menjalankan program desktop Anda di lingkungan UWP adalah dengan menggunakan teknologi Desktop Bridge. Mereka termasuk Desktop App Converter, yang akan mengemas aplikasi Anda yang ada sebagai aplikasi UWP tanpa perlu perubahan kode. Untuk informasi selengkapnya, lihat Jembatan Desktop.

Sisa artikel ini membahas cara port C ++ perpustakaan (DLL dan perpustakaan statis) ke Universelle Windows-Plattform. Anda mungkin ingin port kode Anda sehingga logika C ++ inti Anda dapat digunakan dengan beberapa aplikasi UWP.

Aplikasi UWP berjalan di lingkungan yang dilindungi. Akibatnya, banyak panggilan API Win32, COM, dan CRT yang mungkin membahayakan keamanan platform tidak diizinkan. Opsi /ZW kompiler dapat mendeteksi panggilan tersebut dan menghasilkan kesalahan. Anda dapat menggunakan App Certification Kit di aplikasi Anda untuk mendeteksi kode yang memanggil API yang tidak diizinkan. Untuk informasi selengkapnya, lihat Windows Kit Sertifikasi Aplikasi.

Jika kode sumber tersedia untuk pustaka, Anda dapat mencoba menghilangkan panggilan API yang tidak diizinkan. Untuk daftar API yang tidak diizinkan, lihat API Win32 dan COM untuk aplikasi UWP dan fungsi CRT yang tidak didukung di aplikasi Universelle Windows-Plattform. Beberapa alternatif dapat ditemukan di Alternatif untuk Windows API di aplikasi UWP.

Jika Anda hanya mencoba menambahkan referensi dari Windows Project Universal ke pustaka desktop klasik, Anda mendapatkan pesan kesalahan yang mengatakan pustaka tidak kompatibel. Jika itu adalah perpustakaan statis, Anda dapat menautkan ke perpustakaan Anda dengan menambahkan perpustakaan (.lib file) ke input linker Anda, dengan cara yang sama seperti yang Anda lakukan dalam aplikasi Win32 klasik. Jika hanya pustaka biner yang tersedia, itu satu-satunya pilihan. Pustaka statis ditautkan ke executable aplikasi Anda. Namun, DLL Win32 yang Anda konsumsi di aplikasi UWP harus dikemas ke dalam aplikasi dengan memasukkannya ke dalam proyek dan menandainya sebagai Konten. Untuk memuat DLL Win32 di aplikasi UWP, Anda juga harus menelepon LoadPackagedLibrary alih-alih LoadLibrary atau LoadLibraryEx.

Jika Anda memiliki kode sumber untuk DLL atau pustaka statis, Anda dapat mengkompilasi ulang sebagai proyek UWP dengan menggunakan /ZW opsi kompiler. Kemudian Anda dapat menambahkan referensi ke sana menggunakan Průzkumník řešení, dan menggunakannya di aplikasi C ++ UWP. Tautkan DLL dengan menggunakan pustaka ekspor.

Untuk mengekspos fungsionalitas ke penelepon dalam bahasa lain, Anda dapat mengubah pustaka menjadi Komponen Windows 运行时. Windows 运行时 Komponen berbeda dari DLL biasa karena mereka menyertakan metadata dalam bentuk .winmd file yang menggambarkan konten dengan cara yang dibutuhkan konsumen .NET dan JavaScript. Untuk mengekspos elemen API ke bahasa lain, Anda dapat menambahkan konstruksi C ++/CX, seperti kelas ref, dan membuatnya menjadi publik. Di Windows 10 dan yang lebih baru, kami merekomendasikan pustaka C ++/WinRT, bukan C ++/CX.

Diskusi sebelumnya tidak berlaku untuk komponen COM, yang harus ditangani secara berbeda. Jika Anda memiliki server COM di EXE atau DLL, Anda dapat menggunakannya dalam Windows Project Universal. Paket sebagai komponen COM bebas pendaftaran, tambahkan ke proyek Anda sebagai file Konten, dan instantiate menggunakan CoCreateInstanceFromApp. Untuk informasi selengkapnya, lihat Menggunakan DLL Free-COM di Project C++ Toko Windows.

Jika Anda ingin port perpustakaan COM yang ada ke UWP, Anda juga dapat mengubahnya menjadi Komponen Windows 运行时. Kami merekomendasikan pustaka C ++/WinRT untuk port tersebut, tetapi anda juga dapat menggunakan Windows 运行时 C++ Template Library (WRL). WRL tidak digunakan lagi, dan tidak mendukung semua fitur ATL dan OLE. Apakah port tersebut layak tergantung pada fitur COM, ATL, dan OLE yang dibutuhkan komponen Anda.

Apapun skenario pengembangan yang Anda pilih, Anda harus menyadari sejumlah definisi makro. Anda dapat menggunakan makro ini dalam kode Anda, untuk mengkompilasi kode secara kondisional di bawah win32 desktop klasik dan UWP.

#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PC_APP)
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)

Pernyataan ini masing-masing berlaku untuk aplikasi UWP, Windows Phone Menyimpan aplikasi, keduanya, atau tidak (hanya desktop Win32 klasik). Makro ini hanya tersedia di SDK 8.1 Windows dan versi lebih baru.

Artikel ini berisi prosedur berikut:

Menggunakan DLL Win32 di Aplikasi UWP

Untuk keamanan dan keandalan yang lebih baik, Universal Windows Apps berjalan dalam lingkungan runtime terbatas. Anda tidak bisa hanya menggunakan DLL asli seperti yang Anda lakukan dalam aplikasi desktop Windows klasik. Jika Anda memiliki kode sumber untuk DLL, Anda dapat port kode sehingga berjalan pada UWP. Anda mulai dengan mengubah beberapa pengaturan proyek dan metadata file proyek untuk mengidentifikasi proyek sebagai proyek UWP. Anda akan mengkompilasi ulang kode pustaka menggunakan /ZW opsi, yang memungkinkan C++/CX. Panggilan API tertentu tidak diizinkan di aplikasi UWP karena kontrol yang lebih ketat terkait dengan lingkungan tersebut. Untuk informasi selengkapnya, lihat API Win32 dan COM untuk aplikasi UWP.

Jika Anda memiliki DLL asli yang mengekspor fungsi dengan menggunakan __declspec(dllexport), Anda dapat memanggil fungsi tersebut dari aplikasi UWP dengan mengkompilasi ulang DLL sebagai proyek UWP. Misalnya, misalkan kita memiliki proyek DLL Win32 bernama Giraffe yang mengekspor beberapa kelas dan metodenya, dengan kode seperti file header berikut:

// giraffe.h
// Define GIRAFFE_EXPORTS when building this DLL
#pragma once

#ifdef GIRAFFE_EXPORTS
#define GIRAFFE_API __declspec(dllexport)
#else
#define GIRAFFE_API
#endif

GIRAFFE_API int giraffeFunction();

class Giraffe
{
    int id;
        Giraffe(int id_in);
    friend class GiraffeFactory;

public:
    GIRAFFE_API int GetID();
};

class GiraffeFactory
{
    static int nextID;

public:
    GIRAFFE_API GiraffeFactory();
    GIRAFFE_API static int GetNextID();
    GIRAFFE_API static Giraffe* Create();
};

Dan file kode berikut:

// giraffe.cpp
#include "pch.h"
#include "giraffe.h"

Giraffe::Giraffe(int id_in) : id(id_in)
{
}

int Giraffe::GetID()
{
    return id;
}

int GiraffeFactory::nextID = 0;

GiraffeFactory::GiraffeFactory()
{
    nextID = 0;
}

int GiraffeFactory::GetNextID()
{
    return nextID;
}

Giraffe* GiraffeFactory::Create()
{
    return new Giraffe(nextID++);
}

int giraffeFunction();

Segala sesuatu yang lain dalam proyek (pch.h, dllmain.cpp) adalah bagian dari template proyek Win32 standar. Kode mendefinisikan makro GIRAFFE_API, yang menentukan __declspec(dllexport) kapan GIRAFFE_EXPORTS didefinisikan. Artinya, itu didefinisikan ketika proyek dibangun sebagai DLL, tetapi tidak ketika klien menggunakan giraffe.h header. DLL ini dapat digunakan dalam proyek UWP tanpa mengubah kode sumber. Hanya beberapa pengaturan dan properti proyek yang perlu diubah.

Prosedur berikut berlaku ketika Anda memiliki DLL asli yang mengekspos fungsi menggunakan __declspec(dllexport).

Untuk port DLL asli ke UWP tanpa membuat proyek baru

  1. Buka proyek DLL Anda di Visual Studio.

  2. Buka Properti Project untuk proyek DLL, dan atur Konfigurasi ke Semua Konfigurasi.

  3. Di Properti Project, di bawah tab C/C++>Umum, atur Ekstensi Konsumsi Windows 运行时 ke Ya (/ZW). Properti ini memungkinkan ekstensi komponen (C ++/CX).

  4. Di Průzkumník řešení, pilih simpul proyek, buka menu pintasan, dan pilih Bongkar Project. Kemudian, buka menu pintasan pada simpul proyek yang dibongkar, dan pilih untuk mengedit file proyek. WindowsTargetPlatformVersion Temukan elemen dan ganti dengan elemen berikut.

    <AppContainerApplication>true</AppContainerApplication>
    <ApplicationType>Windows Store</ApplicationType>
    <WindowsTargetPlatformVersion>10.0.10156.0</WindowsTargetPlatformVersion>
    <WindowsTargetPlatformMinVersion>10.0.10156.0</WindowsTargetPlatformMinVersion>
    <ApplicationTypeRevision>10.0</ApplicationTypeRevision>
    

    .vcxproj Tutup file, buka menu pintasan lagi, dan pilih Muat ulang Project.

    Průzkumník řešení sekarang mengidentifikasi proyek tersebut sebagai proyek universal Windows.

  5. Pastikan nama file header yang telah dikompilasi sudah benar. Di bagian Header Yang Telah Dikompilasi Sebelumnya, Anda mungkin perlu mengubah File Header Yang Telah Dikompilasi dari pch.h ke stdafx.h atau sebaliknya jika Anda melihat kesalahan seperti ini:

    kesalahan C2857: Pernyataan '#include' yang ditentukan dengan /Ycpch.h opsi baris perintah tidak ditemukan di file sumber

    Masalahnya adalah template proyek yang lebih lama menggunakan konvensi penamaan yang berbeda untuk file header yang telah dikompilasi sebelumnya. Visual Studio 2019 dan proyek-proyek yang lebih baru menggunakan pch.h.

  6. Membangun proyek. Anda mungkin mendapatkan beberapa kesalahan tentang opsi baris perintah yang tidak kompatibel. Misalnya, opsi yang sekarang tidak digunakan lagi tetapi sering digunakan Enable Minimal Rebuild (/Gm) diatur secara default di banyak proyek C ++ yang lebih lama, dan tidak kompatibel dengan /ZW.

    Beberapa fungsi tidak tersedia saat Anda mengkompilasi untuk Universelle Windows-Plattform. Anda akan melihat kesalahan kompiler tentang masalah apa pun. Atasi kesalahan ini sampai Anda memiliki build yang bersih.

  7. Untuk menggunakan DLL di aplikasi UWP dalam solusi yang sama, buka menu pintasan untuk simpul proyek UWP, dan pilih AddReference>.

    Di bawah ProjectsSolution>, pilih kotak centang di samping proyek DLL, dan pilih tombol OK.

  8. Sertakan file header pustaka di file aplikasi pch.h UWP Anda.

    #include "..\Giraffe\giraffe.h"
    
  9. Tambahkan kode seperti biasa di proyek UWP untuk memanggil fungsi dan membuat jenis dari DLL.

    MainPage::MainPage()
    {
        InitializeComponent();
        GiraffeFactory gf;
        Giraffe* g = gf.Create();
        int id = g->GetID();
    }
    

Menggunakan pustaka statis C++ asli di Aplikasi UWP

Anda dapat menggunakan pustaka statis C ++ asli dalam proyek UWP, tetapi ada beberapa batasan dan batasan yang harus diperhatikan. Mulailah dengan membaca tentang pustaka statis di C ++/CX. Anda dapat mengakses kode asli di perpustakaan statis anda dari aplikasi UWP anda, tetapi tidak disarankan untuk membuat jenis ref publik di perpustakaan statis tersebut. Jika Anda mengkompilasi pustaka statis dengan opsi tersebut /ZW , pustakawan (sebenarnya linker yang menyamar) memperingatkan:

LNK4264: pengarsipan file objek yang dikompilasi dengan /ZW ke dalam pustaka statis; perhatikan bahwa saat menulis jenis Windows 运行时, tidak disarankan untuk menautkan dengan pustaka statis yang berisi metadata Windows 运行时

Namun, Anda dapat menggunakan pustaka statis di aplikasi UWP tanpa menyusunnya kembali dengan /ZW. Pustaka Anda tidak dapat mendeklarasikan jenis ref apa pun atau menggunakan konstruksi C++/CX. Tetapi, jika tujuan Anda hanya untuk menggunakan perpustakaan kode asli, maka Anda dapat melakukannya dengan mengikuti langkah-langkah ini.

Untuk menggunakan pustaka statis C++ asli dalam proyek UWP

  1. Di properti proyek untuk proyek UWP, pilih ConfigurationPropertiesLinkerInput>> di panel kiri. Di panel kanan, tambahkan jalur ke pustaka di properti Dependensi Tambahan . Misalnya, untuk pustaka dalam proyek yang menempatkan outputnya, <SolutionFolder>\Debug\MyNativeLibrary\MyNativeLibrary.libtambahkan jalur Debug\MyNativeLibrary\MyNativeLibrary.librelatif.

  2. Tambahkan pernyataan sertakan untuk mereferensikan file header ke file Anda pch.h (jika ada), atau dalam file apa pun .cpp sesuai kebutuhan, dan mulai menambahkan kode yang menggunakan pustaka.

    #include "..\MyNativeLibrary\MyNativeLibrary.h"
    

    Jangan menambahkan referensi di simpul Referensi di Průzkumník řešení. Mekanisme itu hanya berfungsi untuk Komponen Windows 运行时.

Porting Perpustakaan C ++ ke Komponen Windows 运行时

Misalkan Anda ingin mengkonsumsi API asli di pustaka statis dari aplikasi UWP. Jika Anda memiliki kode sumber untuk pustaka asli, Anda dapat memindahkan kode ke Komponen Windows 运行时. Ini tidak akan menjadi perpustakaan statis lagi; Anda akan mengubahnya menjadi DLL yang dapat Anda gunakan di aplikasi C ++ UWP apa pun. Prosedur ini menjelaskan cara membuat Komponen Windows 运行时 baru yang menggunakan ekstensi C ++/CX. Untuk informasi tentang membuat komponen yang menggunakan C ++/WinRT sebagai gantinya, lihat Windows 运行时 komponen dengan C ++/WinRT.

Saat Anda menggunakan C ++/CX, Anda dapat menambahkan jenis ref dan konstruksi C ++/CX lainnya, yang tersedia untuk klien dalam kode aplikasi UWP apa pun. Anda dapat mengakses jenis ini dari C#, Visual Basic, atau JavaScript. Prosedur dasarnya adalah:

  • Membuat proyek Komponen Windows 运行时 (Universal Windows),
  • salin kode untuk pustaka statis Anda ke dalamnya, dan
  • mengatasi kesalahan apa pun dari kompiler yang disebabkan oleh opsi tersebut /ZW .

Untuk port perpustakaan C ++ ke Komponen Windows 运行时

  1. Buat proyek Komponen Windows 运行时 (Universal Windows).

  2. Tutup proyeknya.

  3. Di Windows проводник, temukan proyek baru. Kemudian, temukan proyek pustaka C ++ yang berisi kode yang ingin Anda porting. Salin file sumber (file header, file kode, dan sumber daya lainnya, termasuk dalam subdirektori) dari proyek perpustakaan C ++ Anda. Tempelkan ke folder proyek baru, pastikan untuk mempertahankan struktur folder yang sama.

  4. Buka kembali proyek Komponen Windows 运行时. Buka menu pintasan untuk simpul proyek di Průzkumník řešení, dan pilih ItemAddExisting>.

  5. Pilih semua file untuk ditambahkan dari proyek asli Anda, dan pilih OK. Ulangi jika perlu untuk subfolder.

  6. Anda sekarang mungkin memiliki beberapa kode duplikat. Jika ada lebih dari satu header yang telah dikompilasi (katakanlah, keduanya stdafx.h dan pch.h), pilih satu untuk disimpan. Salin kode yang diperlukan, seperti sertakan pernyataan, ke dalam kode yang Anda simpan. Kemudian, hapus yang lain, dan di properti proyek, di bawah Header Yang Telah Dikompilasi, pastikan bahwa nama file header sudah benar.

    Jika Anda mengubah file untuk digunakan sebagai header yang telah dikompilasi sebelumnya, pastikan opsi header yang telah dikompilasi sudah benar untuk setiap file. Pilih setiap .cpp file secara bergantian, buka jendela propertinya, dan pastikan semua diatur ke Gunakan (/Yu), kecuali header yang telah dikompilasi sebelumnya, yang harus diatur ke Buat (/Yc).

  7. Bangun proyek dan selesaikan kesalahan apa pun. Kesalahan ini dapat disebabkan oleh penggunaan /ZW opsi, atau dapat disebabkan oleh versi baru SDK Windows. Atau, mereka mungkin mencerminkan dependensi seperti file header yang bergantung pada pustaka Anda, atau perbedaan dalam pengaturan proyek antara proyek lama Anda dan yang baru.

  8. Tambahkan jenis ref publik ke proyek Anda, atau konversi tipe biasa menjadi tipe ref. Gunakan jenis ini untuk mengekspos titik masuk ke dalam fungsionalitas yang ingin Anda panggil dari aplikasi UWP.

  9. Uji komponen dengan menambahkan referensi ke dalamnya dari proyek aplikasi UWP, dan tambahkan beberapa kode untuk memanggil API publik yang Anda buat.

Lihat juga

Porting ke Universelle Windows-Plattform