共用方式為


匯入的成員轉換

更新:2007 年 11 月

這個主題將描述匯入處理序如何轉換下列成員:

  • 方法

  • 屬性

  • 事件

Tlbimp.exe 會將 DefaultMemberAttribute 套用至 DispID 為 0 的任何方法或屬性。請注意,C# 開發人員必須將這些成員視為陣列。如需詳細資訊,請參閱您的程式語言文件。

方法

當 COM Interop 匯入 COM 型別時,它會產生相當於原來 COM 方法簽章的 .NET Framework 方法簽章。在轉換處理過程中,它會將 COM 參數、傳回值和 HRESULT 對應到那些 .NET Framework 方法簽章中的東西,如下圖中所示。

方法簽章轉換

方法簽名碼轉換

您可以使用物件檢視器或使用反映來檢查方法的語法,就像對任何其他 .NET 類別一樣。根據預設,當 COM 物件傳回失敗的 HRESULT 時,Runtime 便會擲回對應的例外狀況。

屬性

COM 開發者可以在介面上宣告屬性和方法。所有屬性都有對應的存取子 (Accessor) 方法,可供設定或取得屬性值。當匯入處理序將具有屬性之介面的型別程式庫描述轉換為中繼資料時,它會建立一個屬性和這個屬性的一個或多個存取子方法。

型別程式庫轉換處理序會以下列方式轉換屬性存取子方法:

  • 具有 [propget] 屬性 (Attribute) 的屬性 (Property) 會成為相同型別的 Managed 屬性 (Property),並且擁有稱為 get_propertyname 的對應方法。

  • 具有 [propput][propputref] 屬性 (Attribute) 的屬性 (Property) 會成為相同型別的 Managed 屬性 (Property),並且擁有稱為 set_propertyname 的對應方法。

  • 同時擁有 [propput][propputref] 兩個屬性 (Attribute) 的屬性 (Property) 會成為:

    • [propputref] 屬性 (Attribute) 相同型別的 Managed 屬性 (Property),並且擁有稱為 set_propertyname 的對應方法

    • [propput] 屬性 (Attribute) 相同型別的另一個存取子方法,名稱為 let_propertyname

以下型別程式庫顯示了原來的屬性。

型別程式庫表示

interface ISample : IDispatch {
    [propget]    HRESULT prop1([out, retval] short *pVal);
    [propput]    HRESULT prop1([in] short newVal);

    [propget]    HRESULT prop2([out, retval] INew **pVal);
    [propputref] HRESULT prop2([in] INew *newVal);

    [propget]    HRESULT prop3([out, retval] INew **ppINew);
    [propput]    HRESULT prop3([in] BSTR text);
    [propputref] HRESULT prop3([in] INew *pINew);
}

下列 Visual Basic 2005 程式碼片段中顯示了轉換的屬性。

Public Property 
    Get Prop1() As Integer … End Get    
    Set Prop1(val as Integer) … End Set
End Property

Public Property 
    Get Prop2() As INew … End Get 
    Set Prop2(val as INew) … End Set
End Property

Public Property
    Get Prop3() As INew … End Get 
    Set Prop3(val as INew) … End Set 
End Property

Public let_prop3(String as Text)

事件

COM 型別程式庫可以定義使用於事件的介面。在程式庫內,做為事件來源的 Coclass 可以藉由指定 [source] 屬性來識別事件介面。事件接收會實作這個介面,而事件來源則是使用它。型別程式庫中未描述的 COM 連接點介面會將事件接收連接到事件的來源。

在下列 IDL 程式碼範例中,Button 類別實作了 IButton 介面,並且做為 IButtonEvents 介面上的事件的來源。

interface IButton {
    HRESULT Init();
}

interface IButtonEvents {
    HRESULT Click([in] int x, [in] int y);
    HRESULT Resize([out, retval] int *pRetval};
}

coclass Button {
    [default] interface IButton;
    [default, source] interface IButtonEvents;
}

.NET 事件模型與 COM 連接點模型有顯著的差異。接收事件的 Managed 類別是藉由傳遞委派給事件來源來接收事件,而不是使用 COM 連接點。COM Interop 服務橋接了這兩種不同的事件模型。

在匯入期間,Tlbimp.exe 會建立一些型別,可以讓 Managed 應用程式接收由 Unmanaged 類別使用 .NET 事件模型所提供的事件。在下列步驟中,Tlbimp.exe 會對先前範例中所示之 Button 類別產生類別和介面:

  1. 匯入處理序會為事件介面中的每一個事件建立委派型別。委派名稱是由事件接收介面、底線、事件名稱和 EventHandler 這個字所組成。例如,在先前範例中的型別程式庫中,Click 事件會成為 IButtonEvents_ClickEventHandler 委派。

    ' A delegate for each event.
    Delegate Sub IButtonEvents_ClickEventHandler(ByVal x As Integer, _
             ByVal y As Integer)
    Delegate Function IButtonEvents_ResizeEventHandler() As Integer
    
    // A delegate for each event.
    delegate void IButtonEvents_ClickEventHandler(int x, int y);
    delegate int IButtonEvents_ResizeEventHandler();
    

    請注意,這個委派的簽章是 Unmanaged 方法簽章的直接轉譯。

  2. Tlbimp.exe 會依照一般方式匯入預設介面,保持介面名稱不變。在這個範例中,這個介面稱為 IButton。

    ' Direct import of original default interface.
    Public Interface IButton
        Sub Init()
    End Interface
    
    // Direct import of original default interface. 
    public interface IButton {
        void Init();
    }
    
  3. Tlbimp.exe 會依照一般方式匯入事件介面,保持介面名稱不變。在這個範例中,這個介面稱為 IButtonEvent。

    ' Direct import of original event interface. 
    ' Not of interest to managed sinks.
    Public Interface IButtonEvents
        Sub Click(ByVal x As Integer, ByVal y As Integer)
        Function Resize() As Integer
    End Interface
    
    // Direct import of original event interface.
    // Not of interest to managed sinks.
    public interface IButtonEvents {
        void Click(int x, int y);
        int Resize();
    }
    
  4. Tlbimp.exe 也會建立第二個事件介面,指定以「_Event」後置字元附加到原來的介面名稱。此第二個事件介面擁有事件 Click 和 Resize 做為成員。它也擁有事件委派的 add 和 remove 方法。在這個範例中,這個介面稱為 IButtonEvents_Event。

    ' Modified version of the event interface with events
    ' for managed sinks.
    
    Public Interface IButtonEvents_Event
            Sub Click As IButtonEvents_Click
            Function Resize() As IButtonEvents_Resize
            Sub add_Click(ByVal Click As IButtonEvents_ClickEventHandler)
            Sub remove_Click(ByVal Click As _
                   IButtonEvents_ClickEventHandler)
            Sub add_Resize(ByVal Resize As _
                   IButtonEvents_ResizeEventHandler)
            Sub remove_Resize(ByVal Resize As _
                   IButtonEvents_ResizeEventHandler)
        End Interface
    // Modified version of the event interface with events 
    // for managed sinks.
    public interface IButtonEvents_Event {
       IButtonEvents_Click Click;
       IButtonEvents_Resize Resize;
       void add_Click(IButtonEvents_ClickEventHandler );
       void remove_Click(IButtonEvents_ClickEventHandler );
       void add_Resize(IButtonEvents_ResizeEventHandler );
       void remove_Resize(IButtonEvents_ResizeEventHandler );
    }
    
    注意事項:

    在少數需要轉換為事件介面的情況下,會轉換為 Tlbimp.exe 產生的介面,而不是原始介面。例如,您必須轉型為 IButtonEvents_Event,而非 IButtonEvents。

  5. Tlbimp.exe 匯入做為事件來源的 Coclass 以確保包含所有明確的實作介面,並附加 Class 於原始類別名稱之後。例如,Button Coclass 會變成 ButtonClass。Tlbimp.exe 也會產生與 Coclass 相同名稱的 Coclass 介面,其使用 _Event 後置字元來實作事件介面。

    ' This is the imported coclass interface.
    ' Note the underscore in IButtonEvents_Event.
        Public Interface Button
            Inherits IButton
            Inherits IButtonEvents_Event
        End Interface
    
        Public Class ButtonClass
            Implements Button
            Implements IButton
            Implements IButtonEvents_Event
            Sub Init()
            End Sub 'Init
        End Class
    
    // This is the imported coclass interface.
    // Note the underscore in IButtonEvents_Event.
    public interface Button:IButton, IButtonEvents_Event {} 
    
    public class ButtonClass:Button,IButton,IButtonEvents_Event 
    {
    void Init(){}
    }
    

請參閱

概念

匯入的程式庫轉換

匯入的模組轉換

匯入的型別轉換

匯入的參數轉換

其他資源

型別程式庫至組件轉換的摘要