Partager via


Conversion d'un type importé

Mise à jour : novembre 2007

Cette rubrique décrit comment le processus d'importation convertit les types suivants :

  • Interfaces

  • Classes

  • Structures

  • Énumérations

  • Constantes

  • Typedef

En général, Tlbimp.exe importe les types sous le nom qu'ils avaient dans la bibliothèque de types d'origine. Dans une bibliothèque de types, les noms doivent être univoques, éliminant ainsi les conflits d'attribution de noms pendant le processus de conversion. Tous les noms de bibliothèque de types valides sont des noms d'assembly valides.

Les types importés ont une portée limitée par l'espace de noms auquel ils appartiennent, le même que celui de la bibliothèque de types d'origine. Les types sont identifiés individuellement par leur nom complet d'espace de noms et de type.

Vous pouvez déterminer explicitement le nom managé d'un type importé en utilisant un attribut de bibliothèque de types dans la bibliothèque de types. Cet identificateur d'attribut défini par l'utilisateur est 0F21F359-AB84-41e8-9A78-36D110E6D2F9. La bibliothèque de types suivante montre l'ajout de l'attribut défini par l'utilisateur.

Représentation de la bibliothèque de types

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

Même si Tlbimp.exe importe la bibliothèque de types dans l'espace de noms AcmeLib, la classe Slingshot devient Acme.WidgetLib.Slingshot.

Interfaces

Lorsque le processus d'importation convertit une interface, il supprime toutes les méthodes IUnknown et IDispatch. La conversion applique GuidAttribute à l'interface pour conserver l'identificateur d'interface (IID) assigné dans la bibliothèque de types et InterfaceTypeAttribute sauf si l'interface est double (dérivant de l'interface IDispatch).

Représentation de la bibliothèque de types

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

Pendant la conversion, le processus d'importation ajoute les méthodes de l'interface de base à l'interface dérivée. Dans l'exemple suivant, New et Start sont ajoutées à l'interface IGadget :

<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();
};

Classes

Le processus d'importation crée une classe managée pour représenter chaque coclasse COM, donnant ainsi à la classe managée le même nom que la coclasse d'origine suivi de Class. Par exemple, la coclasse NewNewer devient NewNewerClass. La conversion ajoute GuidAttribute à la classe afin de capturer l'identificateur de classe (CLSID) de la coclasse.

En plus de la classe managée, le processus d'importation ajoute une interface avec le même nom que la coclasse et applique CoClassAttribute pour identifier le CLSID de la coclasse d'origine. Cette interface possède le même IID que l'interface par défaut de la coclasse. Avec cette interface, les clients peuvent toujours s'inscrire comme récepteurs d'événements.

Contrairement à une coclasse COM, une classe managée peut contenir des membres de classe. Conformément à l'approche du .NET Framework, la conversion ajoute à chaque classe les membres associés à chaque interface implémentée par la coclasse. Les utilisateurs de la classe managée peuvent appeler des méthodes et des propriétés du type managé sans cast préalable vers une interface spécifique. Le processus d'importation ajoute également un constructeur par défaut à chaque coclasse convertie. Un constructeur permet de créer la classe à partir du code managé. (Il n'est pas possible de créer des classes dépourvues de constructeur.) Le constructeur par défaut n'a pas d'argument ; son implémentation appelle le constructeur de la classe de base. Si l'attribut de bibliothèque de types noncreatable est appliqué à la coclasse, le processus d'importation ne crée pas un constructeur par défaut pour la classe.

Dans la mesure où les noms des membres d'interface ne sont pas toujours uniques, des collisions de noms et de DispId peuvent se produire entre les membres. TlbImp.exe résout les collisions de noms en préfixant le nom de l'interface et en faisant précéder d'un trait de soulignement le nom de chaque membre de la classe impliqué dans une collision. Lorsque des noms de membres entrent en collision, la première interface répertoriée dans l'instruction de la coclasse reste inchangée.

Quand des collisions de DispId se produisent, le processus d'importation assigne des DispId aux membres de l'interface par défaut de la coclasse et aucun aux membres de classe en conflit. Cependant, le processus d'importation assigne toujours des DispId aux membres de l'interface.

Représentation de la bibliothèque de types

[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;
}

Les types convertis apparaissent sous la forme suivante :

<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)]…
}

Structures

Les structures définies dans une bibliothèque de types sont importées en tant que métadonnées. Si un champ d'un struct est un type référence, Tlbimp.exe importe le type en tant que IntPtr et applique ComConversionLossAttribute. L'attribut indique que des informations ont été perdues pendant le processus d'importation.

Énumérations

Type Library Importer (Tlbimp.exe) importe des énumérations non managées en tant que types Enum managés.

Constantes

Les constantes ne seront pas importées à partir de la bibliothèque de types dans cette version.

Typedef

Dans une bibliothèque de types, les définitions de types (typedef) ne sont pas importées. Les paramètres et les champs sont plutôt importés en tant que types sous-jacents. Par exemple, un paramètre de type BUTTON_COLOR est importé en tant qu'entier de type, dans la mesure où BUTTON_COLOR est l'alias d'un entier.

Une fois importés, les paramètres et les champs comportent des informations qui les associent à leur type d'origine dans ComAliasNameAttribute. Le processus de conversion applique ComAliasNameAttribute pour associer un champ, un paramètre ou une valeur de retour au nom de la bibliothèque de types et au type de la bibliothèque qui a été utilisé en tant qu'alias.

La représentation de la bibliothèque de types suivante montre que le paramètre cl est typé en tant que BUTTON_COLOR, qui est l'alias d'un entier.

Représentation de la bibliothèque de types

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
    };
};

Les types convertis apparaissent sous la forme suivante :

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();
};

Notez que le type réel BUTTON_COLOR n'est pas défini dans les métadonnées résultantes. Les paramètres typés tels que BUTTON_COLOR dans la bibliothèque de types sont plutôt typés en tant que type sous-jacent, int, et reçoivent l'attribut ComAliasNameAttribute. Ce processus de conversion applique également l'attribut aux arguments sur les méthodes de classe.

Voir aussi

Concepts

Conversion d'une bibliothèque importée

Conversion d'un module importé

Conversion d'un membre importé

Conversion d'un paramètre importé

Autres ressources

Résumé de la conversion d'une bibliothèque de types en assembly