Condividi tramite


Utilizzo di server COM nativi da .NET

Aggiornamento: novembre 2007

In questa sezione vengono descritte le opzioni disponibili per l'utilizzo dei componenti COM esistenti da applicazioni .NET, evidenziando vantaggi e svantaggi di ciascun approccio. L'interoperabilità C++ costituisce in genere il metodo consigliato.

Utilizzo di TLBIMP

L'Utilità di importazione della libreria dei tipi (Tlbimp.exe) di Windows Software Development Kit (SDK) è uno strumento che espone una libreria di tipi COM sotto forma di assembly, denominato assembly di interoperabilità. Questo assembly definisce gli equivalenti gestiti (wrapper) per ogni interfaccia COM in una determinata libreria di tipi.

Quando vengono chiamati metodi dell'assembly di interoperabilità, viene eseguita una transizione da gestito a non gestito e il controllo viene passato al componente COM. Analogamente, quando la funzione COM non gestita restituisce un risultato viene eseguita una transizione da non gestito a gestito. Per impostazione predefinita, viene verificata la presenza di errori in HRESULT COM e viene generata un'eccezione se HRESULT non indica un esito positivo. Analogamente, le query relative alle interfacce e all'inizializzazione dei componenti COM vengono eseguite dall'assembly di interoperabilità e sono pertanto nascoste al codice chiamante.

Gli assembly di interoperabilità non sostituiscono i componenti COM che rappresentano. Le funzioni COM non gestite vengono mantenute nel componente COM, che deve pertanto essere installato e registrato sui computer di destinazione affinché le chiamate all'assembly di interoperabilità abbiano esito positivo.

L'utilizzo di Tlbimp costituisce il modo più semplice per utilizzare un componente COM da codice gestito, ma presenta alcuni svantaggi, soprattutto in caso di interfacce COM estese e/o complesse. Tali svantaggi includono:

  • Tlbimp genera interfacce gestite per ogni interfaccia COM nella libreria di tipi. Poiché non è possibile disattivare questo comportamento, possono risultare assembly di dimensioni considerevoli. L'assembly di interoperabilità generato da Tlbimp per Mshtml.dll supera ad esempio 8 MB. Non è inoltre possibile nascondere un'interfaccia che dovrà essere utilizzata soltanto all'interno del componente COM.

  • Tlbimp supporta un numero limitato di tipi di dati. I tipi non supportati vengono in genere importati nell'ambiente gestito come un tipo IntPtr non indipendente dai tipi generico, richiedendo codice di marshalling complesso e soggetto a errori per l'utilizzo dell'assembly. Talvolta, tuttavia, Tlbimp.exe non è in grado di esporre i membri di un'interfaccia in alcun modo.

  • Tlbimp genera un assembly di interoperabilità separato, che deve essere distribuito con l'applicazione finale.

Se tali svantaggi risultano accettabili, per un esempio vedere Procedura: utilizzare server COM nativi con TLBIMP.

Modifica del codice MSIL

Gli svantaggi di Tlbimp possono essere in parte limitati disassemblando l'assembly di interoperabilità mediante lo strumento Disassembler MSIL (Ildasm.exe), modificando il codice MSIL in modo da rimuovere le definizioni di interfaccia non necessarie e sostituire i tipi di argomento e quindi riassemblando il codice MSIL con lo strumento Assembler MSIL (Ilasm.exe). Questo processo è soggetto a errori e richiede la conoscenza del codice MSIL, dei tipi non gestiti e dei tipi .NET. Deve inoltre essere ripetuto in caso di aggiornamento delle interfacce COM.

Interoperabilità C++

Gli svantaggi di Tlbimp e della modifica del codice MSIL possono essere interamente evitati in Visual C++ poiché, a differenza di Visual Basic e C#, Visual C++ può utilizzare gli oggetti COM direttamente mediante meccanismi COM consueti come CoCreateInstance e QueryInterface. Ciò è consentito dalle funzionalità di interoperabilità C++ grazie alle quali il compilatore inserisce automaticamente il codice di transizione per il passaggio dalle funzioni gestite a quelle non gestite e viceversa.

Utilizzando l'interoperabilità C++, è possibile utilizzare i componenti COM normalmente oppure tramite wrapping all'interno di classi C++. Queste classi wrapper, denominate CRCW (Custom Runtime Callable Wrapper), offrono due vantaggi rispetto all'utilizzo diretto di COM nel codice dell'applicazione:

  • La classe risultate può essere utilizzata da linguaggi diversi da Visual C++.

  • I dettagli dell'interfaccia COM possono essere nascosti al codice client gestito. È possibile utilizzare tipi di dati .NET anziché tipi nativi e i dettagli del marshalling dei dati possono essere completati in modo trasparente all'interno del CRCW.

L'utilizzo di Visual C++ per il wrapping di interfacce COM è illustrato in Procedura: utilizzare server COM nativi con CRCWs.

Indipendentemente dall'utilizzo di COM in modo diretto o tramite CRCW, è necessario eseguire il marshalling dei tipi di argomento diversi da tipi semplici e copiabili. Per informazioni sul marshalling dei dati, vedere Utilizzo delle funzionalità di interoperabilità C++ (PInvoke implicito).

Nota:

Le applicazioni MFC devono essere inizializzate come apartment a thread singolo. Se si chiama CoInitializeEx nell'override di InitInstance, specificare COINIT_APARTMENTTHREADED anziché COINIT_MULTITHREADED. Per ulteriori informazioni, vedere l'articolo 828643 della Knowledge Base "PRB: MFC Application Stops Responding When You Initialize the Application as a Multithreaded Apartment" all'indirizzo https://support.microsoft.com/default.aspx?scid=kb;en-us;828643 (informazioni in lingua inglese).

Vedere anche

Altre risorse

Interoperabilità .NET e nativa