Conversione dei tipi importati

In questo argomento viene descritto in che modo il processo di importazione converte i seguenti tipi:

  • Interfacce

  • Classi

  • Strutture

  • Enumerazioni

  • Costanti

  • Definizioni typedef

In generale, Tlbimp.exe importa i tipi lasciando loro il nome che avevano nella libreria dei tipi originale. I nomi utilizzati all'interno di una libreria dei tipi devono essere univoci. Pertanto il processo di conversione non comporta problemi di conflitti di denominazione. Tutti i nomi validi per una libreria dei tipi sono anche validi per un assembly.

I tipi importati sono caratterizzati da un ambito circoscritto allo spazio dei nomi a cui appartengono, che è lo stesso della libreria dei tipi originale. I tipi vengono identificati individualmente tramite lo spazio dei nomi completo e il nome relativi.

È possibile controllare esplicitamente il nome gestito di un tipo importato utilizzando un attributo della libreria dei tipi nella libreria dei tipi. L'identificatore dell'attributo definito dall'utente è 0F21F359-AB84-41e8-9A78-36D110E6D2F9. Nella libreria dei tipi che segue viene mostrata l'aggiunta dell'attributo definito dall'utente.

Rappresentazione di libreria dei tipi

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

Anche se Tlbimp.exe importa la libreria dei tipi nello spazio dei nomi AcmeLib, la classe Slingshot diviene Acme.WidgetLib.Slingshot.

Interfacce

Quando il processo di importazione converte un'interfaccia, ne estrae tutti i metodi IUnknown e IDispatch. Durante la conversione, all'interfaccia vengono applicati GuidAttribute, allo scopo di conservare l'identificatore di interfaccia (IID, Interface Identifier) assegnato nella libreria dei tipi, e InterfaceTypeAttribute, a meno che l'interfaccia non sia duale, ovvero derivi da IDispatch.

s8sdycxx.collapse_all(it-it,VS.110).gifRappresentazione di libreria dei tipi

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

Durante la conversione, il processo di importazione aggiunge i metodi dell'interfaccia base all'interfaccia derivata. Nell'esempio che segue New e Start vengono aggiunti all'interfaccia 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();
};

Classi

Il processo di importazione crea una classe gestita per rappresentare ciascuna coclasse COM e assegna alla classe gestita lo stesso nome della coclasse originale più il suffisso Class. La coclasse NewNewer diviene ad esempio NewNewerClass. Con la conversione, GuidAttribute viene aggiunto alla classe per acquisire l'identificatore di classe (CLSID, Class Identifier) della coclasse.

Oltre alla classe gestita, il processo di importazione aggiunge un'interfaccia con lo stesso nome della coclasse e applica l'attributo CoClassAttribute per identificare il CLSID della coclasse originale. Tale interfaccia ha lo stesso IID dell'interfaccia predefinita della coclasse. Con questa interfaccia i client possono sempre registrarsi come sink di evento.

Diversamente da una coclasse COM, una classe gestita può contenere membri di classe. In conformità con l'approccio .NET Framework, la conversione aggiunge a ogni classe i membri associati a ciascuna interfaccia implementata dalla coclasse. Gli utenti della classe gestita possono chiamare i metodi e le proprietà del tipo gestito senza prima eseguire il cast in una specifica interfaccia. Il processo di conversione aggiunge anche un costruttore predefinito a ciascuna coclasse convertita. Un costruttore rende possibile la creazione della classe da codice gestito. Non è possibile creare classi prive di un costruttore. Il costruttore predefinito non ha argomenti. La relativa implementazione chiama il costruttore della classe base. Se alla coclasse è stato applicato l'attributo della libreria dei tipi noncreatable, il processo di importazione non creerà un costruttore predefinito per la classe.

Poiché i nomi dei membri di interfaccia non sono sempre univoci, è possibile che si verifichino conflitti di nomi e DispId tra i membri. TlbImp.exe risolve tali conflitti anteponendo il nome dell'interfaccia e un carattere di sottolineatura al nome di ciascun membro della classe che presenta un conflitto. Dove i nomi dei membri sono in conflitto, la prima interfaccia elencata nell'istruzione della coclasse resta immutata.

Dove i DispId sono in conflitto, il processo di importazione assegna DispId ai membri dell'interfaccia predefinita della coclasse e non assegna DispId ai membri della classe in conflitto. In ogni caso, il processo di importazione assegna sempre DispId ai membri dell'interfaccia.

s8sdycxx.collapse_all(it-it,VS.110).gifRappresentazione di libreria dei tipi

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

I tipi convertiti appaiono come segue:

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

Strutture

Le strutture definite all'interno di una libreria dei tipi vengono importate come metadati. Se il campo di una struttura è un tipo di riferimento, il tipo viene importato da Tlbimp.exe come IntPtr e viene applicato l'attributo ComConversionLossAttribute. L'attributo indica che l'informazione è andata persa durante il processo di importazione.

Enumerazioni

L'utilità di importazione della libreria dei tipi (Tlbimp.exe) importa enumerazioni non gestite come tipi Enum gestiti.

Costanti

In questa versione, le costanti non vengono importate dalla libreria dei tipi.

Definizioni typedef

Le definizioni di tipo (typedef) contenute in una libreria dei tipi non vengono importate. Di parametri e campi vengono invece importati i tipi sottostanti. Un parametro di tipo BUTTON_COLOR viene ad esempio importato come tipo integer, poiché BUTTON_COLOR è un alias di integer.

Una volta importati, parametri e campi trasportano le informazioni che li associano al relativo tipo originale nell'oggetto ComAliasNameAttribute. Il processo di conversione applica ComAliasNameAttribute per creare un'associazione tra un campo, un parametro o una valore restituito con il nome della libreria dei tipi e il tipo contenuto nella libreria che è stato usato come alias.

Nella rappresentazione di libreria dei tipi che segue il parametro cl è dichiarato di tipo BUTTON_COLOR, che è un alias di integer.

s8sdycxx.collapse_all(it-it,VS.110).gifRappresentazione di libreria dei tipi

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

I tipi convertiti appaiono come segue:

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

Si noti che il tipo BUTTON_COLOR non è definito nei metadati risultanti. Ai parametri che nella libreria dei tipi sono stati dichiarati di tipo BUTTON_COLOR viene assegnato il tipo sottostante, int, e viene applicato l'attributo ComAliasNameAttribute. Il processo di conversione applica l'attributo anche agli argomenti dei metodi di classe.

Vedere anche

Concetti

Conversione delle librerie importate

Conversione dei moduli importati

Conversione dei membri importati

Conversione dei parametri importati

Altre risorse

Riepilogo della conversione da libreria dei tipi ad assembly