自訂 COM 可呼叫包裝函式
自訂 COM 可呼叫包裝函式是一件簡單的工作。 如果您要公開給 COM 用戶端的型別具備非標準的封送處理需求,請將 System.Runtime.InteropServices.MarshalAsAttribute 屬性套用到方法參數、類別欄位或傳回值,以變更封送處理的行為。
如下圖所示,您可以將 Managed DLL 匯出,而不需要自訂包裝函式 (顯示在左邊)。 或者,您可以將封送處理資訊加入原始程式碼、將它編譯並使用型別程式庫匯出工具 (Tlbexp.exe) 來匯出修改的 DLL,並產生自訂的包裝函式。
在匯出的 DLL 中的封送處理資訊
注意事項 |
---|
所有您要公開給 COM 的 Managed 型別、方法、屬性、欄位和事件都必須是公用的 (Public)。型別必須有公用的預設建構函式 (Constructor),是唯一可以經由 COM 叫用的建構函式。如需詳細資訊,請參閱限定互通的 .NET 型別。 |
當封送處理 Managed 和 Unmanaged 程式碼之間的資料時,Interop 封送處理器必須辨認傳遞的資料表示:
對於 Blittable 型別而言,Managed 和 Unmanaged 表示永遠相同。 例如,4 個位元組整數永遠封送處理成 4 個位元組整數。 Interop 封送處理器使用 Managed 簽章 (Signature) 來決定資料表示。
對於非 Blittable 型別而言,Interop 封送處理器會從它的方法簽章中辨認 Managed 表示,但是無法對 Unmanaged 表示做相同的動作。 若要封送處理非 Blittable 型別,可以使用下列其中一個方法:
允許封送處理器從 Managed 表示來推斷表示。
明確提供 Unmanaged 資料表示。
例如,從 Managed 程式碼封送處理至 Unmanaged 程式碼時,除非您明確套用 MarshalAsAttribute 以將字串封送處理至其他型別 (如 LPWSTR),否則字串會轉換為 BSTR 型別。 您可以將這個屬性套用到型別定義來源內的參數、欄位或傳回值,如下列範例所示。
將 MarshalAsAttribute 套用到參數
Public Sub M1(<MarshalAs(UnmanagedType.LPWStr)> msg As String)
' ...
End Sub
void M1([MarshalAs(UnmanagedType.LPWStr)] string msg)
{
// ...
}
void M1([MarshalAs(UnmanagedType::LPWStr)] String^ msg)
{
// ...
}
將 MarshalAsAttribute 套用到類別內的欄位
Class MsgText
<MarshalAs(UnmanagedType.LPWStr)> _
Public msg As String = ""
End Class
class MsgText
{
[MarshalAs(UnmanagedType.LPWStr)]
public string msg = "";
}
ref class MsgText
{
public:
[MarshalAs(UnmanagedType::LPWStr)]
String^ msg;
MsgText()
{
msg = "";
}
};
將 MarshalAsAttribute 套用到傳回值
Public Function M2() As <MarshalAs(UnmanagedType.LPWStr)> String
Dim msg As New String(New char(128){})
' Load message here ...
Return msg
End Function
[return: MarshalAs(UnmanagedType.LPWStr)]
public string GetMessage()
{
string msg = new string(new char[128]);
// Load message here ...
return msg;
}
[returnvalue: MarshalAs(UnmanagedType::LPWStr)]
String^ GetMessage()
{
String^ msg = gcnew String(gcnew array<Char>(128));
// Load message here ...
return msg;
}
您可以設定 System.Runtime.InteropServices.UnmanagedType 列舉型別來指示所要的 Unmanaged 型別的格式。 在上一個簽章中,msg 資料會當做 Unicode 字元 (LPWStr) 的 Null 結尾緩衝區封送處理。
有時候,Interop 封送處理器需要的資訊比 Managed 和 Unmanaged 資料格式所提供的還要多。 例如,若要封送處理陣列,您必須提供元素類型、陣序、大小和陣列範圍。 您可以使用 MarshalAsAttribute 來指定所要的其他資訊。
請參閱
參考
自訂 COM 可呼叫包裝函式