使用 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 提供較佳的型別安全性,而且實作通常較不繁瑣。 不過,如果無法使用非受控原始程式碼,或跨平臺專案,C++ Interop 不是選項。
C++ COM Interop
Visual C++ 支援的互通性功能在與 COM 元件互通時,提供與其他 .NET 語言的特定優點。 C++ Interop 可讓 COM 元件隨時存取,而不是限制 .NET Framework Tlbimp.exe (類型程式庫匯入工具) 的限制,例如對資料類型的有限支援,以及每個 COM 介面的每個成員的強制公開,C++ Interop 允許存取 COM 元件,而且不需要個別的 Interop 元件。 不同于 Visual Basic 和 C#,Visual C++ 可以直接使用 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++ 元件延伸模組) 。