Share via


自訂 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 可呼叫包裝函式

概念

COM 資料型別

自訂執行階段可呼叫包裝函式

其他資源

使用 COM Interop 封送處理資料

預設的封送處理行為