使用 C++ Interop (隱含 PInvoke)
和其他的 .NET 語言不同,Visual C++ 具有互通性 (Interoperability) 支援,允許 Managed 和 Unmanaged 程式碼存在於相同的應用程式,甚至是同一個檔案中 (須使用 managed, unmanaged Pragma)。這樣 Visual C++ 程式開發人員就可以將 .NET 功能整合至現有的 Visual C++ 應用程式,不會影響到此應用程式的其他部分。
您也可以使用 dllexport dllimport 從 Managed 編譯單位 (Compiland) 呼叫 Unmanaged 函式。
隱含的 PInvoke 在您不需要指定封送處理函式參數的方式或明確呼叫 DllImportAttribute 時可指定之其他細節的時候很有用。
Visual C++ 提供兩種方式,讓 Managed 和 Unmanaged 函式可以互通:
.NET Framework 支援明確的 PInvoke,並且可以在大多數的 .NET 語言中使用。但是顧名思義,C++ Interop 是 Visual C++ 特有的。
C++ Interop 的比較
比起明確的 PInvoke,更推薦您使用 C++ Interop,因為可提供較佳的型別安全 (Type Safety),實作起來比較有趣,較能容忍 Unmanaged API 的修改,並且可以加強效能 (使用明確的 PInvoke 是做不到的)。然而,如果沒有 Unmanaged 原始程式碼或程式碼使用 /clr:safe 編譯時 C++ Interop 就無法使用 (如需詳細資訊,請參閱純粹的和可驗證的程式碼 (C++/CLI))。
C++ COM Interop
Visual C++ 所支援的互通性功能,在與 COM 元件互通時可提供其他 .NET 語言所沒有的特別優點。C++ Interop 不受限於 .NET Framework Tlbimp.exe (型別程式庫匯入工具) 的限制 (例如對資料型別有限的支援,以及強制公開每個 COM 介面中每一個成員),它可以自由存取 COM 元件並且不需要額外的 Interop 組件。如需詳細資訊,請參閱 Using COM from .NET。
Blittable 型別
對於使用簡單內建型別 (請參閱 Blittable 和非 Blittable 型別) 的 Unmanaged API,您不需要特別撰寫程式碼,因為這些資料型別在記憶體中表示方式相同,但是更複雜的資料型別就需要明確的資料封送處理 (Marshaling)。如需範例,請參閱 HOW TO:使用 PInvoke 從 Managed 程式碼呼叫原生 DLL。
範例
// 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");
}
本章節內容
如需在 Interop 案例中使用委派的詳細資訊,請參閱delegate (C++ 元件擴充功能)。