使用 C++ Interop (隱含 PInvoke)

不同于其他 .NET 語言,Visual C++ 具有互通性支援,可讓 Managed 和 Unmanaged 程式碼存在於相同的應用程式中,甚至是在同一個檔案中(使用 Managed、Unmanaged pragmas)。 這可讓 Visual C++ 開發人員將 .NET 功能整合到現有的 Visual C++ 應用程式,而不會干擾應用程式的其餘部分。

您也可以從 Managed 編譯呼叫 Unmanaged 函式,並使用 dllexport、dllimport

當您不需要指定函式參數的封送處理方式,或明確呼叫 DllImportAttribute 時可指定的任何其他詳細資料時,隱含 PInvoke 很有用。

Visual C++ 提供兩種方式,讓 Managed 和 Unmanaged 函式互通:

.NET Framework 支援明確 PInvoke,而且適用于大部分的 .NET 語言。 但正如其名稱所暗示,C++ Interop 是 Visual C++ 特有的。

C++ Interop

C++ Interop 提供更佳的型別安全性,而且實作通常較不乏味。 不過,如果 Unmanaged 原始程式碼無法使用或跨平臺專案,則 C++ Interop 不是選項。

C++ COM Interop

Visual C++ 支援的互通性功能,在與 COM 元件互通時,會比其他 .NET 語言提供特殊優勢。 C++ Interop 不會受限於 .NET Framework Tlbimp.exe (類型程式庫匯入工具) 的限制,例如對資料類型的有限支援,以及每個 COM 介面的每個成員的強制公開,C++ Interop 可讓 COM 元件隨時存取,而且不需要個別的 Interop 元件。 不同于 Visual Basic 和 C#,Visual C++ 可以直接使用一般 COM 機制來使用 COM 物件(例如 CoCreateInstance QueryInterface )。 這可能是因為 C++ Interop 功能導致編譯器自動插入轉換程式碼,以從 Managed 移至 Unmanaged 函式,然後再返回一次。

使用 C++ Interop 時,可以使用 COM 元件,因為它們通常使用,也可以包裝在 C++ 類別內。 這些包裝函式類別稱為自訂執行時間可呼叫包裝函式或 CRCW,而且在應用程式程式碼中直接使用 COM 有兩個優點:

  • 產生的類別可以從 Visual C++ 以外的語言使用。

  • COM 介面的詳細資料可以從 Managed 用戶端程式代碼隱藏。 .NET 資料類型可用來取代原生類型,而且資料封送處理的詳細資料可以在 CRCW 內以透明方式執行。

不論 COM 是直接使用還是透過 CRCW 使用,都必須封送處理簡單、Blittable 類型的引數類型。

Blittable 類型

針對使用簡單、內建類型的 Unmanaged API(請參閱 Blittable 和非 Blittable 類型 ),不需要特殊編碼,因為這些資料類型在記憶體中具有相同標記法,但更複雜的資料類型需要明確的資料封送處理。 如需範例,請參閱 如何:使用 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");
}
Begin beep
Done

本節內容

如需在 Interop 案例中使用委派的詳細資訊,請參閱 委派(C++ 元件延伸模組)。

另請參閱