Cara: Menggunakan kode C++ yang ada di aplikasi Universal Windows Platform

Ada berbagai cara agar Anda dapat menggunakan kode C++ yang ada dalam proyek Platform Windows Universal (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 di C++standar, atau mempertahankan lingkungan kompilasi Win32 klasik untuk beberapa kode. Anda masih dapat melakukannya, dengan pilihan arsitektur yang sesuai. Pertimbangkan semua kode Anda yang berisi UI dan jenis UWP yang diekspos ke pemanggil C#, Visual Basic, dan JavaScript. Kode ini harus berada di proyek Aplikasi Windows dan proyek Komponen Runtime Windows. Kode yang hanya Anda panggil dari C++ (termasuk C++/CX) dapat berada dalam proyek yang dikompilasi dengan /ZW opsi atau proyek C++ standar. Kode khusus biner yang tidak menggunakan API yang tidak diizinkan dapat digunakan dengan menautkannya sebagai pustaka statis. Atau, Anda dapat mengemasnya dengan aplikasi sebagai konten dan memuatnya di DLL.

Mungkin cara term mudah untuk menjalankan program desktop Anda di lingkungan UWP adalah dengan menggunakan teknologi Desktop Bridge. Mereka termasuk Pengonversi Aplikasi Desktop, yang akan mengemas aplikasi Anda yang ada sebagai aplikasi UWP tanpa perubahan kode yang diperlukan. Untuk mengetahui informasi selengkapnya, lihat Desktop Bridge.

Sisa artikel ini membahas cara memindahkan pustaka C++ (DLL dan pustaka statis) ke Platform Windows Universal. Anda mungkin ingin mem-port kode Anda sehingga logika C++ inti Anda dapat digunakan dengan beberapa aplikasi UWP.

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

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 Platform Windows Universal. Beberapa alternatif dapat ditemukan di Alternatif untuk WINDOWS API di aplikasi UWP.

Jika Anda hanya mencoba menambahkan referensi dari Proyek Windows Universal ke pustaka desktop klasik, Anda mendapatkan pesan kesalahan yang mengatakan pustaka tidak kompatibel. Jika ini adalah pustaka statis, Anda dapat menautkan ke pustaka Anda dengan menambahkan pustaka (.lib file) ke input linker Anda, dengan cara yang sama seperti yang Anda lakukan di aplikasi Win32 klasik. Jika hanya pustaka biner yang tersedia, itu adalah satu-satunya opsi. Pustaka statis ditautkan ke dalam aplikasi Anda yang dapat dieksekusi. Namun, DLL Win32 yang Anda gunakan dalam aplikasi UWP harus dipaketkan ke dalam aplikasi dengan menyertakannya dalam proyek dan menandainya sebagai Konten. Untuk memuat DLL Win32 di aplikasi UWP, Anda juga harus memanggil 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 pengkompilasi. Kemudian Anda dapat menambahkan referensi ke referensi tersebut menggunakan Penjelajah Solusi, dan menggunakannya di aplikasi C++ UWP. Tautkan DLL dengan menggunakan pustaka ekspor.

Untuk mengekspos fungsionalitas ke pemanggil dalam bahasa lain, Anda dapat mengonversi pustaka menjadi Komponen Runtime Windows. Komponen Runtime Windows berbeda dari DLL biasa karena menyertakan metadata dalam bentuk .winmd file yang menjelaskan konten dengan cara yang diperlukan konsumen .NET dan JavaScript. Untuk mengekspos elemen API ke bahasa lain, Anda dapat menambahkan konstruksi C++/CX, seperti kelas ref, dan membuatnya publik. Di Windows 10 dan yang lebih baru, kami merekomendasikan pustaka C++/WinRT alih-alih 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 di Proyek Windows Universal. Kemas sebagai komponen COM bebas pendaftaran, tambahkan ke proyek Anda sebagai file Konten, dan buat instans menggunakan CoCreateInstanceFromApp. Untuk informasi selengkapnya, lihat Menggunakan DLL FREE-COM di Proyek C++ Windows Store.

Jika Anda ingin memindahkan pustaka COM yang ada ke UWP, Anda juga dapat mengonversinya menjadi Komponen Runtime Windows. Kami merekomendasikan pustaka C++/WinRT untuk port tersebut , tetapi dimungkinkan juga untuk menggunakan Windows Runtime C++ Template Library (WRL). WRL tidak digunakan lagi, dan tidak mendukung semua fitur ATL dan OLE. Apakah port seperti itu layak tergantung pada fitur COM, ATL, dan OLE yang diperlukan komponen Anda.

Skenario pengembangan apa pun yang Anda pilih, Anda harus mengetahui sejumlah definisi makro. Anda dapat menggunakan makro ini dalam kode Anda, untuk mengkompilasi kode secara kondisional di bawah desktop klasik Win32 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, aplikasi Windows Telepon Store, keduanya, atau tidak (hanya desktop Win32 klasik). Makro ini hanya tersedia di Windows SDK 8.1 dan yang lebih baru.

Artikel ini berisi prosedur berikut:

Menggunakan DLL Win32 di Aplikasi UWP

Untuk keamanan dan keandalan yang lebih baik, Universal Windows Apps berjalan di lingkungan runtime terbatas. Anda tidak dapat menggunakan DLL asli apa pun seperti yang Anda lakukan di aplikasi desktop Windows klasik. Jika Anda memiliki kode sumber untuk DLL, Anda dapat mem-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 yang 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, kita memiliki proyek WIN32 DLL 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 templat proyek Win32 standar. Kode mendefinisikan makro GIRAFFE_API, yang menentukan __declspec(dllexport) kapan GIRAFFE_EXPORTS ditentukan. Artinya, ini 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 memindahkan DLL asli ke UWP tanpa membuat proyek baru

  1. Buka proyek DLL Anda di Visual Studio.

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

  3. Di Properti Proyek, di bawah tab C/C++>General, atur Gunakan Ekstensi Runtime Windows ke Ya (/ZW). Properti ini memungkinkan ekstensi komponen (C++/CX).

  4. Di Penjelajah Solusi, pilih simpul proyek, buka menu pintasan, dan pilih Bongkar Proyek. Kemudian, buka menu pintasan pada simpul proyek yang tidak dimuat, 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 Proyek.

    Penjelajah Solusi sekarang mengidentifikasi proyek sebagai proyek Universal Windows.

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

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

    Masalahnya adalah bahwa templat proyek yang lebih lama menggunakan konvensi penamaan yang berbeda untuk file header yang telah dikommpilasikan sebelumnya. Proyek Visual Studio 2019 dan yang lebih baru menggunakan pch.h.

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

    Beberapa fungsi tidak tersedia saat Anda mengkompilasi untuk Platform Windows Universal. Anda akan melihat kesalahan pengkompilasi 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 Tambahkan>Referensi.

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

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

    #include "..\Giraffe\giraffe.h"
    
  9. Tambahkan kode seperti biasa dalam 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 pustaka statis dari aplikasi UWP Anda, tetapi tidak disarankan untuk membuat jenis ref publik di pustaka statis seperti itu. Jika Anda mengkompilasi pustaka statis dengan /ZW opsi , pustakawan (sebenarnya linker dalam penyamaran) memperingatkan:

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

Namun, Anda dapat menggunakan pustaka statis di aplikasi UWP tanpa mengkompilasi ulang dengan /ZW. Pustaka Anda tidak dapat mendeklarasikan jenis ref apa pun atau menggunakan konstruksi C++/CX. Tetapi, jika tujuan Anda hanya untuk menggunakan pustaka 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 Input Penghubung>Properti>Konfigurasi di panel kiri. Di panel kanan, tambahkan jalur ke pustaka di properti Dependensi Tambahan. Misalnya, untuk pustaka dalam proyek yang menempatkan output-nya di <SolutionFolder>\Debug\MyNativeLibrary\MyNativeLibrary.lib, tambahkan 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 tambahkan kode yang menggunakan pustaka.

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

    Jangan tambahkan referensi di simpul Referensi di Penjelajah Solusi. Mekanisme tersebut hanya berfungsi untuk Komponen Runtime Windows.

Memindahkan Pustaka C++ ke Komponen Runtime Windows

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

Saat 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 Windows Runtime Component (Universal Windows),
  • salin kode untuk pustaka statis Anda ke dalamnya, dan
  • mengatasi kesalahan apa pun dari pengkompilasi yang /ZW disebabkan oleh opsi .

Untuk memindahkan pustaka C++ ke Komponen Runtime Windows

  1. Buat proyek Windows Runtime Component (Universal Windows).

  2. Tutup proyek.

  3. Di Windows File Explorer, temukan proyek baru. Kemudian, temukan proyek pustaka C++ yang berisi kode yang ingin Anda port. Salin file sumber (file header, file kode, dan sumber daya lainnya, termasuk dalam subdirektori) dari proyek pustaka C++Anda. Tempelkan ke folder proyek baru, pastikan untuk mempertahankan struktur folder yang sama.

  4. Buka kembali proyek Komponen Runtime Windows. Buka menu pintasan untuk simpul proyek di Penjelajah Solusi, dan pilih Tambahkan>Item yang Ada.

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

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

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

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

  8. Tambahkan jenis ref publik ke proyek Anda, atau konversi jenis biasa ke jenis 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 komponen tersebut dari proyek aplikasi UWP, dan tambahkan beberapa kode untuk memanggil API publik yang Anda buat.

Baca juga

Port ke Platform Windows Universal