使用 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++ 元件擴充功能)

請參閱

概念

從 Managed 程式碼呼叫原生函式