在 Managed 程式碼中建立原型
更新:2007 年 11 月
本主題旨在說明如何存取 Unmanaged 函式,同時也介紹了數種在 Managed 程式碼中用來加註方法定義的屬性物件欄位。如需示範如何建構 .NET 架構的宣告,以便與平台叫用一起使用的範例,請參閱使用平台叫用封裝處理資料。
您必須先知道函式名稱以及匯出該函式之 DLL 的名稱,然後才能從 Managed 程式碼存取 Unmanaged DLL 函式。有了這項資訊,您就可以開始對 DLL 中所實作之 Unmanaged 函式撰寫 Managed 定義。此外,您也可以調整平台叫用建立函式和在函式之間封送處理資料的方式。
注意事項: |
---|
配置字串的 Win32 API 函式可以讓您使用如 LocalFree 這類方法釋放字串。平台叫用則是以不同方式處理這類參數。對於平台叫用呼叫,請將參數變為 IntPtr 型別,而非 String 型別。請使用 System.Runtime.InteropServices.Marshal 類別提供的方法,以手動方式將型別轉換為 String,再以手動方式予以釋放。 |
宣告的基本概念
對於 Unmanaged 函式的 Managed 定義會依語言而有所不同,如下列範例中所示。如需完整的程式碼範例,請參閱平台叫用範例。
Imports System.Runtime.InteropServices
Public Class Win32
Declare Auto Function MessageBox Lib "user32.dll" _
(ByVal hWnd As Integer, _
ByVal txt As String, ByVal caption As String, _
ByVal Typ As Integer) As IntPtr
End Class
如果要將 BestFitMapping、CallingConvention、ExactSpelling、PreserveSig、SetLastError 或 ThrowOnUnmappableChar 欄位套用至 Microsoft Visual Basic 2005 宣告,您必須使用 DllImportAttribute 屬性,而非 Declare 陳述式。
Imports System.Runtime.InteropServices
Public Class Win32
<DllImport ("user32.dll", CharSet := CharSet.Auto)> _
Public Shared Function MessageBox (ByVal hWnd As Integer, _
ByVal txt As String, ByVal caption As String, _
ByVal Typ As Integer) As IntPtr
End Function
End Class
using System.Runtime.InteropServices;
[DllImport("user32.dll")]
public static extern IntPtr MessageBox(int hWnd, String text,
String caption, uint type);
using namespace System::Runtime::InteropServices;
[DllImport("user32.dll")]
extern "C" IntPtr MessageBox(int hWnd, String* pText,
String* pCaption unsigned int uType);
調整定義
不論您是否有明確設定屬性欄位,這些欄位都會定義 Managed 程式碼的行為。平台叫用會依據組件中各個以中繼資料形式存在的各個欄位的預設值來運作的。您可以經由調整一或多個欄位中的值,借以改變預設的行為。許多情況下,您會使用 DllImportAttribute 來設定值。
下表所列為平台叫用相關的完整屬性欄位集。對於每個欄位,這個表格都包括了預設值和有關如何使用這些欄位來定義 Unmanaged DLL 函式的資訊連結。
欄位 |
說明 |
---|---|
啟用或停用最適合的對應。 |
|
指定用來傳遞方法引數的呼叫慣例。預設值為 WinAPI,相當於 32 位元 Intel 平台上的 __stdcall。 |
|
控制函式名稱改變 (Name Mangling) 和字串引數應如何封送處理至函式的方式。預設值為 CharSet.Ansi。 |
|
指定要呼叫的 DLL 進入點 (Entry Point)。 |
|
控制是否要修改進入點以對應字元集。預設值會因程式語言而不同。 |
|
控制 Managed 方法簽章是否應轉換為會傳回 HRESULT 的 Unmanaged 簽章,並可擁有傳回值的額外 [out, retval] 引數。 預設值為 true (這個簽章不應轉換)。 |
|
可讓呼叫端能使用 Marshal.GetLastWin32Error API 函式判斷,執行方法時是否發生錯誤。在 Visual Basic 中,預設為 true,在 C# 和 C++ 中,預設值為 false。 |
|
控制轉換為 ANSI "?" 字元而無法對應的 Unicode 字元擲回例外狀況。 |
如需詳細的參考資訊,請參閱 DllImportAttribute 類別。