Technology Experience

Contenuti gestiti da Igor Damiani
posts - 949, comments - 2741, trackbacks - 15120

My Links

News

  • Questo blog si propone di raccogliere riflessioni, teoriche e pratiche, su tutto quello che riguarda il world-computing che mi sta attorno: programmazione in .NET, software attuale e futuro, notizie provenienti dal web, tecnologia in generale, open-source.

    L'idea è quella di lasciare una sorta di patrimonio personale, una raccolta di idee che un giorno potrebbe farmi sorridere, al pensiero di dov'ero e cosa stavo facendo.

    10/05/2005,
    Milano

Archives

Post Categories

Generale

[70-536, #30] Primi passi con il mondo Interop

Introduzione
Fino ad oggi abbiamo sempre discusso con un mondo completamente managed, ovvero il cui codice è scritto al 100% in linguaggi previsti dal FX (VB.NET e C# in primo luogo), e che quindi gira all'interno del CLR. Possiamo però andare oltre, e permettere al nostro codice di oltrepassare le normali barriere ed avere a che fare con il managed unmanaged, ovvero tutto quello che riguarda codice Win32, mondo COM e via dicendo.

Ovviamente, il fatto che sia possibile non vuol dire che sia una cosa semplice, nè tantomeno che siamo esenti da rischi. La difficoltà principale è saper mappare in memoria gli oggetti managed in modo tale che siano utilizzabili dalle funzioni native Win32, e viceversa. Tale operazione è nota con il termine di marshaling: vi rimando alla tabella in fondo a questo articolo per tutti i dettagli del caso. Oggi cominciamo con le cose più semplici: vediamo infatti come poter aggiungere ad un nostro progetto .NET un riferimento ad un componente COM, sia esso un OCX, una DLL ActiveX o una type library.

Un riferimento ai componenti di Microsoft Word
Il concetto che ruota a queste problematiche è che .NET crea una classe managed che il nostro codice utilizza come wrapper per tutte le chiamate al mondo unmanaged. Ad esempio, se apriamo un qualsiasi progetto .NET con Visual Studio 2005, clicchiamo con il pulsanto destro sul nome del progetto e selezioniamo la voce Add Reference, l'IDE ci propone una finestra di dialogo dalla quale possiamo selezionare qualsiasi cosa ci passi per la testa: oggetti .NET, oggetti COM, altri progetti inseriti nella nostra solution, e via dicendo. Il tab Browse ci permette di sfogliare il contenuto del nostro hard-disk alla ricerca di files DLL, TLB, OLB, OCX ed EXE che vogliamo mettere nei riferimenti del nostro progetto.

Supponiamo per esempio di voler interoperare con Microsoft Word all'interno della nostra applicazione. Una delle possibili soluzioni consiste nell'aggiungere come riferimento il file MSWORD.OLB, seguendo il procedimento indicato prima. Questa semplice operazione si traduce in:

  • la creazione di un nuovo assembly in managed code, ottenuto partendo dal file MSWORD.OLB
  • l'inserimento del nuovo assembly nella GAC
  • l'aggiunta del nuovo assembly come riferimento al nostro progetto .NET

Così facendo, otteniamo in tutto e per tutto un riferimento valido all'object model di Word, utilizzabile quindi direttamente nel nostro codice attraverso la classe wrapper. Tale wrapper viene inserito in un namespace dedicato, che va quindi referenziato tramite la solita using. Per esempio:

Microsoft.Office.Interop.Word.Application appWord =
    
new Microsoft.Office.Interop.Word.Application();
Document doc = appWord.Documents.Open( 
/*Parametri*/ );

Il metodo Open esposto dall'oggetto Documents richiede un gran numero di parametri obbligatori, cosa che invece non accade per esempio quando facciamo la stessa con VB6. Il motivo è che molti dei parametri sono opzionali: in .NET questo comportamento si attua sfruttando l'overloading dei metodi. Questo esempio vale solo a scopo didattico, per cui ho deciso comunque di mantenerlo.

Il tool Tlbimp.exe
Il meccanismo di creazione della classe wrapper in managed code è disponibile anche attraverso il tool tlbimp.exe fornito dal FX2.0. Questo tool richiede essenzialmente il nome del file DLL di cui si vuole creare il wrapper. Rispetto alle funzionalità esposte dall'IDE, abbiamo diverse marce in più:

  • l'opzione /namespace: permette di specificare il namespace attraverso il quale sarà possibile raggiungere la nuova classe wrapper
  • l'opzione /out: permette di specificare il nome del file generato
  • l'opzione /keyfile: permette di specificare un file SNK per firmare con uno strong name l'assembly (tale file viene generato dal tool sn.exe, cliccare qui per maggiori informazioni)

Questo tool, quindi, permette di generare la classe wrapper al di fuori dell'IDE ed in modo completamente indipendente. L'unico parametro davvero necessario è il nome del file (tlbFile), che deve contenere obbligatoriamente una COM type library.

Compilare un progetto che fa uso di Interop
Esiste una pagina su MSDN che descrive come compilare un progetto .NET che usa InterOp per interagire con il mondo unmanaged. Se compiliamo dall'IDE, non cambia nulla: la classe wrapper nasconde il mondo unmanaged e siamo a posto. Se compiliamo da command-line, assicuriamoci di utilizzare il parametro /reference: del compilatore per referenziare l'assembly contenente la classe wrapper che ci serve.

Deploy di un'applicazione che fa uso di InterOp
Se stiamo facendo il deploy di un'applicazione InterOp, dobbiamo considerare se i nostri assembly wrapper devono essere condivisi fra più applicazioni. La pagina dedicata su MSDN è piuttosto chiara. Se gli assembly wrapper sono condivisi, vale la pena firmarli con uno strong name, inserirli nella GAC (che alla fin fine è un centralized repository fatto apposta per questo scopo) ed il gioco è fatto. Se gli assembly sono privati per una certa applicazione, il deploy deve essere fatto nella stessa directory dove si trova l'applicazione.

Dietro le quinte: come fa Tlbimp a convertire?
A partire da questa pagina su MSDN, vengono descritte quali sono le logiche che Tlbimp.exe mette in campo per convertire dal mondo COM al mondo managed. Si parla quindi di Imported Member Conversion, Imported Library Conversion, Imported Module Conversion e via dicendo.

powered by IMHO 1.2

Print | posted on Monday, June 5, 2006 1:32 PM | Filed Under [ Esame 70-536 ]

Feedback

Gravatar

# re: [70-536, #30] Primi passi con il mondo Interop

Due cose:
per l'interoperabilità con Office si DEVONO usare i PIA...
Altrimenti chi arriva da google si mette a farseli a mano e sbaglia. :-)

Secondo, visto che l'esame è sia su C# sia su VB, con scelta iniziale, con VB si possono usare i parametri opzionali senza fare comandi di 80 righe, e quindi è importante dirlo.
Quando si fa interoperabilità con office si usa vb proprio per questo motivo...
6/5/2006 3:21 PM | Lorenzo Barbieri
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET