Freigeben über


Konvertieren importierter Typen

In diesem Abschnitt wird die Konvertierung der folgenden Typen durch den Importvorgang beschrieben:

  • Schnittstellen

  • Klassen

  • Strukturen

  • Enumerationen

  • Konstanten

  • Typedefs

Im Allgemeinen importiert Tlbimp.exe Typen mit demselben Namen, den sie in der ursprünglichen Typbibliothek trugen. Die Namen innerhalb einer Typbibliothek müssen eindeutig sein. Dadurch werden Konflikte bei der Benennung während des Konvertierungsprozesses vermieden. Alle gültigen Typbibliotheknamen sind auch gültige Assemblynamen.

Importierte Typen sind immer für den Namespace ausgelegt, zu dem sie gehören. Dies ist derselbe wie in der ursprünglichen Typbibliothek. Typen werden anhand ihres vollständigen Namespace und Typnamens identifiziert.

Sie können den verwalteten Namen eines importierten Typs explizit steuern, indem sie in der Typbibliothek ein Typbibliotheksattribut verwenden. Der benutzerdefinierte Attributbezeichner ist 0F21F359-AB84-41e8-9A78-36D110E6D2F9. In der folgenden Typbibliothek wird die Addition der benutzerdefinierten Attribute gezeigt.

Typbibliothekdarstellung

[  uuid(…),
    version(1.0)
]
library AcmeLib {
    interface Widget {};
    [custom(0F21F359-AB84-41e8-9A78-36D110E6D2F9, 
     "Acme.WidgetLib.Slingshot")]
    coclass Slingshot {};
};

Obwohl die Typbibliothek mit Tlbimp.exe in den AcmeLib-Namespace importiert wird, wird die Slingshot-Klasse zu Acme.WidgetLib.Slingshot.

Schnittstellen

Wird eine Schnittstelle durch den Importvorgang konvertiert, werden alle IUnknown-Methoden und IDispatch-Methoden entfernt. Bei der Konvertierung wird GuidAttribute auf die Schnittstelle angewendet, um die in der Typbibliothek zugewiesene IID (Interface Identifier, Schnittstellenbezeichner) sowie InterfaceTypeAttribute beizubehalten, es sei denn, die Schnittstelle ist dual (abgeleitet von IDispatch).

Typbibliothekdarstellung

[uuid(…), ]
interface IWidget : IUnknown {
    HRESULT New()
    HRESULT Start()
};
[uuid(…), ]
interface IGadget : IWidget {
    HRESULT Baz()
};

Durch den Importvorgang werden bei der Konvertierung die Methoden der Basisschnittstelle zu der abgeleiteten Schnittstelle hinzugefügt. Im folgenden Beispiel werden New und Start zur IGadget-Schnittstelle hinzugefügt:

<Guid(…), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Interface IWidget
    Sub [New]()
    Sub Start()
End Interface

<Guid(…), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Interface IGadget
    Inherits IWidget
    Shadows Sub [New]()
    Shadows Sub Start()
    Sub Baz()
End Interface
[Guid(…), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IWidget {
    void New();
    void Start();
};
[Guid(…), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IGadget : IWidget {
    new void New();
    new void Start();
    void Baz();
};

Klassen

Der Importvorgang erstellt eine verwaltete Klasse, um jede Co-Klasse zu repräsentieren. Die verwaltete Klasse erhält dabei denselben Namen wie die ursprüngliche Co-Klasse, erweitert um den Zusatz Class. Aus der NewNewer-Co-Klasse wird z. B. NewNewerClass. Bei der Konvertierung wird GuidAttribute zur Klasse hinzugefügt, um den Klassenbezeichner (CLSID) der Co-Klasse zu erfassen.

Zusätzlich zu der verwalteten Klasse wird beim Importvorgang eine Schnittstelle hinzufügt, die denselben Namen trägt wie die Co-Klasse, und es wird das CoClassAttribute angewendet, um die CLSID der ursprünglichen Co-Klasse zu identifizieren. Diese Schnittstelle besitzt dieselbe IID wie die Standardschnittstelle der Co-Klasse. Mithilfe dieser Schnittstelle können Clients jederzeit als Ereignissenke registriert werden.

Im Gegensatz zur COM-Co-Klasse kann eine verwaltete Klasse Klassenmember enthalten. Gemäß dem .NET Framework-Modell fügt die Konvertierung jeder Klasse die Member hinzu, die jeder durch die Co-Klasse implementierten Schnittstelle zugeordnet sind. Benutzer der verwalteten Klasse können Methoden und Eigenschaften des verwalteten Typs aufrufen, ohne zuerst auf eine bestimmte Schnittstelle zurückzugreifen. Durch den Importvorgang wird auch ein Standardkonstruktor zu jeder konvertierten Co-Klasse hinzugefügt. Ein Konstruktor ermöglicht das Erstellen der Klasse mit verwaltetem Code. (Klassen ohne Konstruktor können nicht erstellt werden). Der Standardkonstruktor verfügt nicht über Argumente; seine Implementierung ruft den Basisklassenkonstruktor auf. Wenn das Typbibliotheksattribut noncreatable von der Co-Klasse übernommen wird, wird durch den Importvorgang kein Standardkonstruktor für die Klasse erstellt.

Da die Namen von Schnittstellenmembern nicht immer eindeutig sind, kann es zu Konflikten bezüglich Namen und DispIds kommen. Diese Konflikte werden durch TlbImp.exe gelöst, indem Schnittstellennamen mit einem Präfix und Namen konfliktierender Klassenmember mit einem Unterstrich versehen werden. Wo Konflikte zwischen Membernamen auftreten, bleibt die erste in der Co-Klassenanweisung aufgeführte Schnittstelle unverändert.

Bei DispId-Konflikten weist der Importvorgang den Membern der Standardschnittstelle der Co-Klasse DispIds zu, aber nicht den vom Konflikt betroffenen Klassenmembern. Schnittstellenmembern werden jedoch immer DispIds zugewiesen.

Typbibliothekdarstellung

[uuid(…)]
interface INew : IDispatch {
    [id(0x100)] HRESULT DoFirst();
    [id(0x101)] HRESULT DoSecond();
}
[uuid(…)]
interface INewer : IDispatch {
    [id(0x100)] HRESULT DoNow();
    [id(0x101)] HRESULT DoSecond();
}
[uuid(…)]
coclass NewNewer  {
    [default] interface INew;
    interface INewer;
}

Die konvertierten Typen werden folgendermaßen angezeigt:

<Guid(…)> Public Interface INew
    …
End Interface

<Guid(…)> Public Interface INewer
    …
End Interface

<Guid(…)> Public Interface NewNewer
Inherits INew
    …
End Interface

<Guid(…)> Public Class NewNewerClass
Implements INew   
Implements INewer
Implements NewNewer
' Method implementation
     <DispId(100)> _
      …
End Class  
[Guid(…)]
public interface INew {…}

[Guid(…)]
public interface INewer {…}

[Guid(…)]
public interface NewNewer : INew {…}

[Guid(…)]
public class NewNewer : INew, INewer, NewNewer{
// Method implementation.
     [DispId(100)]…
}

Strukturen

Strukturen, die innerhalb einer Typbibliothek definiert sind, werden als Metadaten importiert. Ist ein Strukturfeld ein Referenztyp, wird der Typ als IntPtr durch Tlbimp.exe importiert und ComConversionLossAttribute angewendet. Dieses Attribut gibt an, dass während des Imports Information verloren gegangen sind.

Enumerationen

Das Type Library Importer-Tool (Tlbimp.exe) importiert nicht verwaltete Enumerationen als verwaltete Enum-Typen.

Konstanten

In dieser Version werden Konstanten nicht aus der Typbibliothek importiert.

Typedefs

Typdefinitionen (typedefs) innerhalb einer Typbibliothek werden nicht importiert. Stattdessen werden Parameter und Felder als zugrunde liegende Typen importiert. Ein Parameter des Typs BUTTON_COLOR beispielsweise wird als ganze Zahl eines Typs importiert, da BUTTON_COLOR ein Alias für eine ganze Zahl darstellt.

Nach dem Import enthalten Parameter und Felder Information, durch die sie ihrem Originaltyp im ComAliasNameAttribute zugeordnet werden. Durch den Konvertierungsprozess wird ComAliasNameAttribute angewendet, um ein Feld, einen Parameter oder einen Rückgabewert dem Namen der Typbibliothek und des Typs innerhalb der Bibliothek zuzuordnen, der als Alias verwendet wurde.

In der folgenden Darstellung einer Typbibliothek wird gezeigt, dass der cl-Parameter vom Typ BUTTON_COLOR ist, der ein Alias für eine ganze Zahl darstellt.

Typbibliothekdarstellung

library MyLib {
    typedef [public] int BUTTON_COLOR;

    interface ISee {
        HResult SetColor([in] BUTTON_COLOR cl);
        HResult GetColor([out, retval] BUTTON_COLOR *cl);
    };
   
    coclass See {
        [default] interface ISee
    };
};

Die konvertierten Typen werden folgendermaßen angezeigt:

public interface ISee {
    void SetColor([ComAliasName("MyLib.BUTTON_COLOR")]] int cl);
    [return: ComAliasName("MyLib.BUTTON_COLOR")] int GetColor();
};

public class See {
    public void SetColor([ComAliasName("MyLib.BUTTON_COLOR")]] int cl);
    [return: ComAliasName("MyLib.BUTTON_COLOR")] int GetColor();
};

Beachten Sie, dass der aktuelle Typ BUTTON_COLOR nicht in den resultierenden Metadaten definiert ist. Stattdessen erhalten die Parameter, die in der Typbibliothek vom Typ BUTTON_COLOR sind, den zugrunde liegende Typ int und das Attribut ComAliasNameAttribute. Dieser Konvertierungsprozess wendet das Attribut auch auf Argumente von Klassenmethoden an.

Siehe auch

Konzepte

Konvertieren importierter Bibliotheken

Konvertieren importierter Module

Konvertieren importierter Member

Konvertieren importierter Parameter

Weitere Ressourcen

Zusammenfassung: Konvertieren einer Typbibliothek in eine Assembly