Bagikan melalui


Menggunakan interop C++ (PInvoke implisit)

Tidak seperti bahasa .NET lainnya, Visual C++ memiliki dukungan interoperabilitas yang memungkinkan kode terkelola dan tidak terkelola ada di aplikasi yang sama dan bahkan dalam file yang sama (dengan pragma terkelola dan tidak dikelola ). Ini memungkinkan pengembang Visual C++ untuk mengintegrasikan fungsionalitas .NET ke dalam aplikasi Visual C++ yang ada tanpa mengganggu aplikasi lainnya.

Anda juga dapat memanggil fungsi yang tidak dikelola dari compiland terkelola menggunakan dllexport, dllimport.

PInvoke implisit berguna ketika Anda tidak perlu menentukan bagaimana parameter fungsi akan dirusak, atau detail lain yang dapat ditentukan saat secara eksplisit memanggil DllImportAttribute.

Visual C++ menyediakan dua cara untuk fungsi terkelola dan tidak terkelola untuk beroperasi:

PInvoke eksplisit didukung oleh .NET Framework dan tersedia di sebagian besar bahasa .NET. Tetapi seperti namanya, C++ Interop khusus untuk Visual C++.

Interop C++

C++ Interop memberikan keamanan jenis yang lebih baik, dan biasanya kurang melelahkan untuk diterapkan. Namun, Interop C++ bukan opsi jika kode sumber yang tidak dikelola tidak tersedia, atau untuk proyek lintas platform.

C++ COM Interop

Fitur interoperabilitas yang didukung oleh Visual C++ menawarkan keunggulan khusus dibandingkan bahasa .NET lainnya dalam hal interoperabilitas dengan komponen COM. Alih-alih terbatas pada pembatasan .NET Framework Tlbimp.exe (Type Library Importer), seperti dukungan terbatas untuk jenis data dan paparan wajib setiap anggota setiap antarmuka COM, Interop C++ memungkinkan komponen COM diakses sesering mungkin dan tidak memerlukan rakitan interop terpisah. Tidak seperti Visual Basic dan C#, Visual C++ dapat menggunakan objek COM secara langsung menggunakan mekanisme COM biasa (seperti CoCreateInstance dan QueryInterface). Ini dimungkinkan karena fitur C++ Interop yang menyebabkan pengkompilasi secara otomatis menyisipkan kode transisi untuk berpindah dari fungsi yang dikelola ke tidak terkelola dan kembali lagi.

Menggunakan C++ Interop, komponen COM dapat digunakan karena biasanya digunakan atau dapat dibungkus di dalam kelas C++. Kelas pembungkus ini disebut pembungkus yang dapat dipanggil runtime kustom, atau CRCW, dan mereka memiliki dua keuntungan daripada menggunakan COM secara langsung dalam kode aplikasi:

  • Kelas yang dihasilkan dapat digunakan dari bahasa selain Visual C++.

  • Detail antarmuka COM dapat disembunyikan dari kode klien terkelola. Jenis data .NET dapat digunakan sebagai pengganti jenis asli, dan detail marshaling data dapat dilakukan secara transparan di dalam CRCW.

Terlepas dari apakah COM digunakan secara langsung atau melalui CRCW, jenis argumen selain jenis sederhana yang dapat di-blittable harus di-marshal.

Tipe Blittable

Untuk API tidak terkelola yang menggunakan jenis intrinsik sederhana dan intrinsik (lihat Jenis Blittable dan Non-Blittable), tidak ada pengodean khusus yang diperlukan karena jenis data ini memiliki representasi yang sama dalam memori, tetapi jenis data yang lebih kompleks memerlukan marshaling data eksplisit. Misalnya, lihat Cara: Memanggil DLL Asli dari Kode Terkelola Menggunakan PInvoke.

Contoh

// vcmcppv2_impl_dllimp.cpp
// compile with: /clr:pure user32.lib
using namespace System::Runtime::InteropServices;

// Implicit DLLImport specifying calling convention
extern "C" int __stdcall MessageBeep(int);

// explicit DLLImport needed here to use P/Invoke marshalling because
// System::String ^ is not the type of the first parameter to printf
[DllImport("msvcrt.dll", EntryPoint = "printf", CallingConvention = CallingConvention::Cdecl,  CharSet = CharSet::Ansi)]
// or just
// [DllImport("msvcrt.dll")]
int printf(System::String ^, ...);

int main() {
   // (string literals are System::String by default)
   printf("Begin beep\n");
   MessageBeep(100000);
   printf("Done\n");
}
Begin beep
Done

Di Bagian Ini

Untuk informasi tentang menggunakan delegasi dalam skenario interop, lihat mendelegasikan (Ekstensi Komponen C++).

Baca juga