Konvertieren exportierter Member

In diesem Thema wird die Konvertierung der folgenden Member durch den Exportvorgang beschrieben:

  • Methoden

  • Eigenschaften

  • Ereignisse

Methoden

COM-Clients erwarten das Aufrufen von Methoden, die Übergabe vertrauter COM-Datentypen wie z. B. Parameter sowie den anschließenden Empfang von HRESULTs. Im .NET-Bereich allerdings unterliegen die Klassen keinen solchen Beschränkungen hinsichtlich Rückgabetypen (und verwenden keine HRESULTs).

Um beiden Modellen gerecht zu werden, verfügt jede Methode eines verwalteten Typs über eine .NET-Signatur und eine implizierte COM-Signatur. Beide Signaturen sind in der Regel sehr unterschiedlich. .NET-Clients interagieren über die .NET-Signatur mit dem Server, während COM-Clients (möglicherweise gleichzeitig) über die COM-Signatur mit dem Server interagieren. Der Server implementiert die Methode mit der .NET-Signatur. Der Laufzeit-Marshalldienst ist für die Bereitstellung eines Stubs mit der COM-Signatur verantwortlich, der den Aufruf zur verwalteten Methode delegiert.

HRESULT-Umwandlung

Eine verwaltete Signatur wird in eine nicht verwaltete Signatur konvertiert, indem der verwaltete Rückgabewert in einen [out, retval]-Parameter und der Typ des nicht verwalteten Rückgabewerts in HRESULT umgewandelt wird. Die DoSomething-Methode kann beispielsweise über folgende Signaturen verfügen:

Verwaltete Signatur

short DoSomething(short i);

Nicht verwaltete Signatur

HRESULT DoSomething([in] short i, [out, retval] short *rv);

Beachten Sie, dass die COM-Signatur HRESULT zurückgibt und einen zusätzlichen out-Parameter für den Rückgabewert hat. Der Rückgabewert von einer verwalteten Implementierung wird immer als [out, retval]-Parameter zurückgegeben, der am Ende der nicht verwalteten Signatur hinzugefügt wird. Die nicht verwaltete Signatur hingegen gibt immer HRESULT zurück. Wenn die verwaltete Methode eine void-Rückgabe hat, lässt die Laufzeit den [out, retval]-Parameter weg. Beispiel:

Verwaltete Signatur

void DoSomething(short i);

Nicht verwaltete Signatur

HRESULT DoSomething([in] short i);

In einigen Fällen empfiehlt es sich, die verwaltete Signatur unverändert zu lassen. Verwenden Sie dazu das PreserveSigAttribute. Beispiel:

Verwaltete Signatur

[PreserveSig] short DoSomething(short i);

Nicht verwaltete Signatur

short DoSomething ([in] short i);

Mit zwei verschiedenen Methodensignaturen kann die Klasse nahtlos von COM-Clients und .NET-Clients verwendet werden. Darüber hinaus können sowohl COM-Clients als auch .NET-Clients eine .NET-Klasse gleichzeitig verwenden. Als Klassenautor implementieren Sie nur die verwaltete Signatur. Bei der Verwendung von Tlbexp.exe (oder einer äquivalenten API) wird die Signatur automatisch in eine für die Klasse generierte Typbibliothek exportiert.

Überladene Methoden

Obwohl .NET überladene Methoden unterstützt, ist für die Bindung durch die Schnittstelle IDispatch nur der Methodenname erforderlich, nicht die vollständige Methodensignatur. Deshalb können überladene Methoden nicht unterstützt werden. Um jedoch den Zugriff auf überladene Methoden eines Typs zu gewähren, werden die Namen der überladenen Methoden durch Tlbexp.exe mit einer Ordinalzahl ergänzt. Dadurch ist jeder Methodenname eindeutig.

In den folgenden verwalteten und nicht verwalteten Signaturen wird die Verwendung der Zahlen dargestellt:

Verwaltete Signatur

interface INew {
public:
    void DoSomething();
    void DoSomething(short s);
    void DoSomething(short l);
    void DoSomething(float f);
    void DoSomething(double d);
}

Nicht verwaltete Signatur

interface INew {
    void DoSomething();
    void DoSomething_2(short s);
    void DoSomething_3(short l);
    void DoSomething_4(float f);
    void DoSomething_5(double d);
}

Die COM-Signatur der Methoden wird als einzelne DoSomething-Methode angezeigt, auf die eine Serie ergänzter DoSomething_x-Methoden folgt. Der Anfangswert von x beträgt 2 und wird schrittweise mit jeder überladenen Form der Methode erhöht. Beachten Sie, dass einige überladene Methoden von einem Basistyp vererbt werden können. Es gibt jedoch keine Garantie dafür, dass überladene Methoden bei einer Aktualisierung der Typversion dieselbe Nummer behalten.

Obwohl .NET-Clients die überladene Form der Methode verwenden können, müssen COM-Clients auf die ergänzten Methoden zugreifen. Objektkataloge zeigen alle Formen ergänzter Methoden mit der Methodensignatur an. Dadurch können Sie die korrekte Methode auswählen. Der spät gebundene Client kann auch IDispatch::GetIdsOfNames aufrufen und den ergänzten Namen übergeben, um die DispID einer beliebigen überladenen Methode zu erhalten.

Eigenschaften

Verwaltete Klassen und verwaltete Schnittstellen können Eigenschaften haben. Eine verwaltete Eigenschaft besteht aus einem speziellen Datentyp, der über eine zugeordnete get-Methode und set-Methode verfügen kann. Diese Methoden werden wie alle anderen Methoden auch getrennt definiert. Im folgenden Codebeispiel wird eine Schnittstelle dargestellt, die eine Height-Eigenschaft enthält. Klassen, die die Schnittstelle implementieren, müssen eine get-Methode und eine set-Methode für die Eigenschaft bereitstellen.

    interface IMammal {
 
    IMammal Mother{get;set;}
    IMammal Father{get;set;}
    int     Height{get;set;}
    int     Weight{get;set;}

    }

    class Human : IMammal
    {
        int weight;
        int height;
        IMammal father;
        IMammal mother;

        public IMammal Mother { get { return mother; } set { mother = value; } }
        public IMammal Father { get { return father; } set { father = value; } }
        public int Height { get { return height; } set { height = value; } }
        public int Weight { get { return weight; } set { weight = value; } }
    }

Beim Exportieren wird durch Tlbexp.exe die set-Methode für die Eigenschaft in [propput] konvertiert und die get-Methode für die Eigenschaft in [propget] konvertiert. Der Eigenschaftenname in COM bleibt derselbe wie der Name der verwalteten Eigenschaft. Diese Regel hat die folgenden Ausnahmen:

  • Wenn der Eigenschaftentyp – Werttypen ausgenommen – eine Klasse oder eine Schnittstelle ist, wird die set-Methode für die Eigenschaft zu [propputref]. Dadurch erhalten die Parameter einen zusätzlichen Indirection-Level.

  • Wenn die Eigenschaft nicht über eine get-Methode oder eine set-Methode verfügt, lässt Tlbexp.exe die Eigenschaft in der Typbibliothek weg.

Verwaltete Felder werden wie Eigenschaften in die Typbibliothek exportiert. Der Laufzeit-Marshalldienst generiert die get-Methode und die set-Methode automatisch für alle öffentlichen Felder. In der folgenden Darstellung der Typbibliothek wird gezeigt, wie während des Konvertierungsvorgangs durch Tlbexp.exe für jedes Feld eine [propput] (oder [propputref])-Funktion und eine [propget]-Funktion generiert wird.

Typbibliothekdarstellung

interface IMammal : IDispatch {
         [propget]    HRESULT Mother([out, retval] IMammal** pRetVal);
         [propputref] HRESULT Mother([in] IMammal* pRetVal);
         [propget]    HRESULT Father([out, retval] IMammal** pRetVal);
         [propputref] HRESULT Father([in] IMammal* pRetVal);
         [propget]    HRESULT Height([out, retval] long* pRetVal);
         [propput]    HRESULT Height([in] long pRetVal);
         [propget]    HRESULT Weight([out, retval] long* pRetVal);
         [propput]    HRESULT Weight([in] long pRetVal);
         [propget]    HRESULT Age([out, retval] long* pRetVal);
         [propput]    HRESULT Age([in] long pRetVal);    
};

Ereignisse

Wenn Sie mit dem Ereignismodell in COM-Interop nicht vertraut sind, finden Sie weitere Informationen unter Verwaltete und nicht verwaltete Ereignisse. Verwaltete Typen implementieren Ereignisse, indem sie ein Delegat-basiertes Ereignismodell verwenden. Im folgenden Code z. B. löst die Class1Events-Schnittstelle das Click-Ereignis aus.

    Public Delegate Sub ClickDelegate()
    <GuidAttribute("1A585C4D-3371-48dc-AF8A-AFFECC1B0967"), _
    InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)>

    Public Interface Class1Event
        Sub Click ()
    End Interface
<ComSourceInterfaces("Class1Event, EventSrc")> _
    Public Class Class1
        Public Event Click As ClickDelegate
   End Class
    public delegate void Click();

    public interface Class1Event
    {
        void Click();
    }
   [ComSourceInterfaces("Class1Event, EventSrc")]
    public class Class1
    {
        public event ClickDelegate Click;
    }

Beim Exportieren markiert Tlbexp.exe die Ereignisschnittstelle in der Co-Klasse als Quelle. In der folgenden Darstellung der Typbibliothek ist die exportierte ComClass1Events-Schnittstelle als Quellschnittstelle markiert.

Typbibliothekdarstellung

    disinterface Class1Event {
        properties:
        methods:
        [id(0x60020000)]
        HRESULT Click();
    };

    coclass Class1
    {
    …
    [default, source] Class1Event;
    };

Siehe auch

Konzepte

Konvertierung von exportierten Assemblys

Konvertieren exportierter Module

Konvertieren exportierter Typen

Konvertieren exportierter Parameter

Weitere Ressourcen

Zusammenfassung: Konvertieren einer Assembly in eine Typbibliothek