Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Dopo che un thread ha inizializzato la libreria COM, è sicuro che il thread usi le interfacce COM. Per usare un'interfaccia COM, il programma crea innanzitutto un'istanza di un oggetto che implementa tale interfaccia.
In generale, esistono due modi per creare un oggetto COM:
- Il modulo che implementa l'oggetto potrebbe fornire una funzione progettata specificamente per creare istanze di tale oggetto.
- In alternativa, COM fornisce una funzione di creazione generica denominata CoCreateInstance.
Ad esempio, prendere l'ipotetico oggetto Shape
dall'argomento Che cos'è un'interfaccia COM?. In questo esempio, l'oggetto Shape
implementa un'interfaccia denominata IDrawable
. La libreria grafica che implementa l'oggetto Shape
potrebbe esportare una funzione con la firma seguente.
// Not an actual Windows function.
HRESULT CreateShape(IDrawable** ppShape);
Data questa funzione, è possibile creare un nuovo oggetto Shape
come indicato di seguito.
IDrawable *pShape;
HRESULT hr = CreateShape(&pShape);
if (SUCCEEDED(hr))
{
// Use the Shape object.
}
else
{
// An error occurred.
}
Il parametro ppShape è di tipo puntatore a puntatore aIDrawable
. Se questo modello non è stato visto in precedenza, il doppio riferimento indiretto potrebbe risultare sconcertante.
Prendere in considerazione i requisiti della funzione CreateShape
. La funzione deve restituire un puntatore IDrawable
al chiamante. Ma il valore restituito della funzione è già usato per il codice di errore/esito positivo. Pertanto, il puntatore deve essere restituito tramite un argomento alla funzione . Il chiamante passerà una variabile di tipo IDrawable*
alla funzione e la funzione sovrascriverà questa variabile con un nuovo puntatore IDrawable
. In C++, esistono solo due modi per sovrascrivere un valore di parametro: pass by reference o pass by address. COM utilizza quest'ultimo pass-by-address. L'indirizzo di un puntatore è un puntatore a un puntatore, quindi il tipo di parametro deve essere IDrawable**
.
Di seguito è riportato un diagramma che consente di visualizzare le operazioni in corso.
La funzione CreateShape
usa l'indirizzo di pShape (&pShape
) per scrivere un nuovo valore del puntatore in pShape.
CoCreateInstance: modo generico per creare oggetti
La funzione CoCreateInstance fornisce un meccanismo generico per la creazione di oggetti. Per comprendere CoCreateInstance, tenere presente che due oggetti COM possono implementare la stessa interfaccia e un oggetto può implementare due o più interfacce. Pertanto, una funzione generica che crea oggetti richiede due informazioni.
- Oggetto da creare.
- Quale interfaccia ottenere dall'oggetto.
Ma come si indicano queste informazioni quando si chiama la funzione? In COM un oggetto o un'interfaccia viene identificato assegnando un numero a 128 bit, denominato identificatore univoco globale (GUID). I GUID vengono generati in modo da renderli effettivamente univoci. I GUID rappresentano una soluzione al problema relativo alla creazione di identificatori univoci senza un'autorità di registrazione centrale. I GUID vengono talvolta chiamati identificatori universalmente univoci (UUID). Prima di COM, sono stati usati in DCE/RPC (Distributed Computing Environment/Remote Procedure Call). Esistono diversi algoritmi per la creazione di nuovi GUID. Non tutti questi algoritmi garantiscono rigorosamente l'univocità, ma la probabilità di creare accidentalmente lo stesso valore GUID due volte è estremamente piccola, in modo efficace zero. I GUID possono essere usati per identificare qualsiasi tipo di entità, non solo oggetti e interfacce. Tuttavia, questo è l'unico uso che ci riguarda in questo modulo.
Ad esempio, la libreria Shapes
potrebbe dichiarare due costanti GUID:
extern const GUID CLSID_Shape;
extern const GUID IID_IDrawable;
È possibile presupporre che i valori numerici effettivi a 128 bit per queste costanti siano definiti altrove. La costante CLSID_Shape identifica l'oggetto Shape
, mentre la costante IID_IDrawable identifica l'interfaccia IDrawable
. Il prefisso "CLSID" è l'acronimo di class identifiere il prefisso IID sta per identificatore di interfaccia. Queste sono convenzioni di denominazione standard in COM.
Dato questi valori, si creerebbe una nuova istanza di Shape
come indicato di seguito:
IDrawable *pShape;
hr = CoCreateInstance(CLSID_Shape, NULL, CLSCTX_INPROC_SERVER, IID_IDrawable,
reinterpret_cast<void**>(&pShape));
if (SUCCEEDED(hr))
{
// Use the Shape object.
}
else
{
// An error occurred.
}
La funzioneCoCreateInstanceha cinque parametri. Il primo e il quarto parametro sono l'identificatore di classe e l'identificatore dell'interfaccia. In effetti, questi parametri indicano alla funzione "Creare l'oggetto Shape e assegnarmi un puntatore all'interfaccia IDrawable".
Impostare il secondo parametro su NULL. Per altre informazioni sul significato di questo parametro, vedere l'argomento aggregation nella documentazione COM. Il terzo parametro accetta un set di flag il cui scopo principale è quello di specificare il contesto di esecuzione per l'oggetto. Il contesto di esecuzione specifica se l'oggetto viene eseguito nello stesso processo dell'applicazione; in un processo diverso nello stesso computer; o in un computer remoto. Nella tabella seguente vengono illustrati i valori più comuni per questo parametro.
Bandiera | Descrizione |
---|---|
CLSCTX_INPROC_SERVER | Stesso processo. |
CLSCTX_LOCAL_SERVER | Processo diverso, stesso computer. |
CLSCTX_REMOTE_SERVER | Computer diverso. |
CLSCTX_ALL | Usare l'opzione più efficiente supportata dall'oggetto. La classificazione, dalla più efficiente alla meno efficiente, è: "in-process", "out-of-process" e "cross-computer". |
La documentazione per un determinato componente potrebbe indicare il contesto di esecuzione supportato dall'oggetto. In caso contrario, usare CLSCTX_ALL. Se si richiede un contesto di esecuzione non supportato dall'oggetto, la funzioneCoCreateInstance restituisce il codice di errore REGDB_E_CLASSNOTREG. Questo codice di errore può anche indicare che CLSID non corrisponde ad alcun componente registrato nel computer dell'utente.
Il quinto parametro per CoCreateInstance riceve un puntatore all'interfaccia. Poiché CoCreateInstance è un meccanismo generico, questo parametro non può essere fortemente tipizzato. Al contrario, il tipo di dato è void**e il chiamante deve convertire l'indirizzo del puntatore a un tipo void**. Questo è lo scopo del reinterpret_cast nell'esempio precedente.
È fondamentale controllare il valore restituito di CoCreateInstance. Se la funzione restituisce un codice di errore, il puntatore all'interfaccia COM non è valido e il tentativo di dereferenziazione può causare l'arresto anomalo del programma.
Internamente, la funzione CoCreateInstance usa varie tecniche per creare un oggetto. Nel caso più semplice, cerca l'identificatore di classe nel Registro di sistema. La voce del Registro di sistema punta a una DLL o a un file EXE che implementa l'oggetto . CoCreateInstance può anche usare informazioni da un catalogo COM+ o da un manifesto SxS (Side-by-Side). Indipendentemente, i dettagli risultino chiari per chi chiama. Per ulteriori informazioni sui dettagli interni di CoCreateInstance, consultare Client e Server COM.
L'esempio Shapes
che abbiamo usato è un po' forzato, quindi ora passiamo a un esempio reale di COM in azione: visualizzare la finestra di dialogo Apri per permettere all'utente di selezionare un file.
Prossimo
esempio : finestra di dialogo Apri