Attributi di C++ per COM e .NET

Microsoft definisce un set di attributi C++ che semplificano la programmazione COM e lo sviluppo Common Language Runtime di .NET Framework. Quando si includono attributi nei file di origine, il compilatore funziona con dll del provider per inserire codice o modificare il codice nei file oggetto generati. Questi attributi facilitano la creazione di file con estensione idl, interfacce, librerie dei tipi e altri elementi COM. Nell'ambiente di sviluppo integrato (IDE) gli attributi sono supportati dalle procedure guidate e dal Finestra Proprietà.

Mentre gli attributi eliminano alcuni dei codici dettagliati necessari per scrivere oggetti COM, è necessario un background nei concetti fondamentali COM per usarli al meglio.

Nota

Per gli attributi standard C++, vedere Attributi.

Scopo degli attributi

Gli attributi estendono C++ in direzioni attualmente non possibili senza interrompere la struttura classica del linguaggio. Gli attributi consentono ai provider (DLL separate) di estendere in modo dinamico la funzionalità del linguaggio. L'obiettivo principale degli attributi è semplificare la creazione di componenti COM, oltre ad aumentare il livello di produttività dello sviluppatore di componenti. Gli attributi possono essere applicati a quasi qualsiasi costrutto C++, ad esempio classi, membri dati o funzioni membro. Di seguito è riportato un'evidenziazione dei vantaggi offerti da questa nuova tecnologia:

  • Espone una convenzione di chiamata familiare e semplice.

  • Usa il codice inserito, che, a differenza delle macro, viene riconosciuto dal debugger.

  • Consente una semplice derivazione dalle classi di base senza dettagli di implementazione onerosi.

  • Sostituisce la grande quantità di codice IDL richiesto da un componente COM con alcuni attributi concisi.

Ad esempio, per implementare un sink di eventi semplice per una classe ATL generica, è possibile applicare l'attributo event_receiver a una classe specifica, ad CMyReceiveresempio . L'attributo event_receiver viene quindi compilato dal compilatore Microsoft C++, che inserisce il codice corretto nel file oggetto.

[event_receiver(com)]
class CMyReceiver
{
   void handler1(int i) { ... }
   void handler2(int i, float j) { ... }
}

È quindi possibile configurare i CMyReceiver metodi handler1 e handler2 gestire gli eventi (usando la funzione intrinseca __hook) da un'origine evento, che è possibile creare usando event_source.

Meccanismi di base degli attributi

Esistono tre modi per inserire attributi nel progetto. In primo luogo, è possibile inserirli manualmente nel codice sorgente. In secondo luogo, è possibile inserirli usando la griglia delle proprietà di un oggetto nel progetto. Infine, è possibile inserirli usando le varie procedure guidate. Per altre informazioni sull'uso della finestra Proprietà e delle varie procedure guidate, vedere Progetti di Visual Studio - C++.

Come in precedenza, quando il progetto viene compilato, il compilatore analizza ogni file di origine C++, generando un file oggetto. Tuttavia, quando il compilatore rileva un attributo, viene analizzato e verificato sintatticamente. Il compilatore chiama quindi in modo dinamico un provider di attributi per inserire codice o apportare altre modifiche in fase di compilazione. L'implementazione del provider varia a seconda del tipo di attributo. Ad esempio, gli attributi correlati ad ATL vengono implementati da Atlprov.dll.

Nella figura seguente viene illustrata la relazione tra il compilatore e il provider di attributi.

Diagram showing component attribute communication.

Nota

L'utilizzo degli attributi non modifica il contenuto del file di origine. L'unica volta che il codice dell'attributo generato è visibile durante le sessioni di debug. Inoltre, per ogni file di origine nel progetto, è possibile generare un file di testo che visualizza i risultati della sostituzione dell'attributo. Per altre informazioni su questa procedura, vedere /Fx (Merge Injected Code) e Debug del codice inserito.

Analogamente alla maggior parte dei costrutti C++, gli attributi hanno un set di caratteristiche che ne definiscono l'utilizzo appropriato. Questo viene definito contesto dell'attributo e viene indirizzato nella tabella del contesto dell'attributo per ogni argomento di riferimento dell'attributo. Ad esempio, l'attributo coclasse può essere applicato solo a una classe o a una struttura esistente, anziché all'attributo cpp_quote , che può essere inserito in qualsiasi punto all'interno di un file di origine C++.

Compilazione di un programma con attributi

Dopo aver inserito gli attributi di Visual C++ nel codice sorgente, è possibile che il compilatore Microsoft C++ producano automaticamente una libreria dei tipi e un file con estensione idl. Le opzioni del linker seguenti consentono di compilare file con estensione tlb e idl:

Alcuni progetti contengono più file con estensione idl indipendenti. Questi vengono usati per produrre due o più file con estensione tlb e, facoltativamente, associarli al blocco di risorse. Questo scenario non è attualmente supportato in Visual C++.

Inoltre, il linker di Visual C++ restituirà tutte le informazioni relative all'attributo IDL in un singolo file MIDL. Non sarà possibile generare due librerie di tipi da un singolo progetto.

Contesti di attributi

Gli attributi C++ possono essere descritti usando quattro campi di base: la destinazione a cui possono essere applicati (Si applica a), se sono ripetibili o meno (ripetibile), la presenza necessaria di altri attributi (attributi obbligatori) e incompatibilità con altri attributi (attributi non validi). Questi campi sono elencati in una tabella associata nell'argomento di riferimento di ogni attributo. Ognuno di questi campi è descritto di seguito.

Si applica a

Questo campo descrive i diversi elementi del linguaggio C++ che sono destinazioni legali per l'attributo specificato. Ad esempio, se un attributo specifica "classe" nel campo Si applica a , questo indica che l'attributo può essere applicato solo a una classe C++ legale. Se l'attributo viene applicato a una funzione membro di una classe, viene generato un errore di sintassi.

Per altre informazioni, vedere Attributi in base all'utilizzo.

Ripetibile

Questo campo indica se l'attributo può essere applicato ripetutamente alla stessa destinazione. La maggior parte degli attributi non è ripetibile.

Attributi obbligatori

Questo campo elenca gli altri attributi che devono essere presenti (ovvero applicati alla stessa destinazione) affinché l'attributo specificato funzioni correttamente. Non è raro che un attributo contenga voci per questo campo.

Attributi non validi

Questo campo elenca altri attributi incompatibili con l'attributo specificato. Non è raro che un attributo contenga voci per questo campo.

Eseguire il debug di codice inserito

Il ricorso agli attributi può semplificare notevolmente la programmazione in C++. Per altre informazioni, vedere Concetti. Alcuni attributi sono interpretati direttamente dal compilatore. Con altri attributi è invece possibile inserire codice nell'origine del programma, il quale verrà quindi compilato dal compilatore. Questo codice inserito rende più semplice la programmazione perché riduce la quantità di codice che è necessario scrivere. A volte, tuttavia, può accadere che un bug arresti l'applicazione mentre è in esecuzione il codice inserito. Quando ciò accade, può essere utile esaminare tale codice e Visual Studio prevede due metodi per farlo:

  • Visualizzare il codice inserito nella finestra Disassembly.

  • Creare, tramite /Fx, un file di origine unito contenente il codice originale e il codice inserito.

Nella finestra Disassembly vengono visualizzate le istruzioni in linguaggio assembly che corrispondono al codice sorgente e al codice inserito da attributi. Nella finestra Disassembly sono riportate anche le annotazioni del codice sorgente.

Per attivare l'annotazione del codice sorgente

  • Fare clic con il pulsante destro del mouse sulla finestra Disassembly e scegliere Mostra codice sorgente dal menu di scelta rapida.

    Se si conosce la posizione di un attributo in una finestra di origine, sarà possibile usare il menu di scelta rapida per trovare il codice inserito nella finestra Disassembly.

Per visualizzare il codice inserito

  1. Il debugger deve essere in modalità di interruzione.

  2. In una finestra di codice sorgente, portare il cursore davanti all'attributo di cui si desidera visualizzare il codice inserito.

  3. Fare clic con il pulsante destro del mouse e scegliere Vai a disassembly dal menu di scelta rapida.

    Se l'attributo si trova vicino al punto di esecuzione corrente, sarà possibile scegliere la finestra Disassembly dal menu Debug.

Per visualizzare il codice disassembly al punto di esecuzione corrente

  1. Il debugger deve essere in modalità di interruzione.

  2. Scegliere Finestre dal menu Debug e fare clic su Disassembly.

In questa sezione

Domande frequenti sulla programmazione con attributi
Attributi per gruppo
Attributi per utilizzo
Riferimento alfabetico agli attributi