Funzione CreateStreamOnHGlobal (combaseapi.h)
La funzione CreateStreamOnHGlobal crea un oggetto flusso che usa un handle di memoria HGLOBAL per archiviare il contenuto del flusso. Questo oggetto è l'implementazione fornita da OLE dell'interfaccia IStream .
L'oggetto flusso restituito supporta sia la lettura che la scrittura, non viene transazionata e non supporta il blocco dell'area. L'oggetto chiama la funzione GlobalReAlloc per aumentare il blocco di memoria in base alle esigenze.
Sintassi
HRESULT CreateStreamOnHGlobal(
[in] HGLOBAL hGlobal,
[in] BOOL fDeleteOnRelease,
[out] LPSTREAM *ppstm
);
Parametri
[in] hGlobal
Handle di memoria allocato dalla funzione GlobalAlloc oppure se è necessario allocare un nuovo handle NULL . L'handle deve essere allocato come spostabile e non visualizzabile.
[in] fDeleteOnRelease
Valore che indica se l'handle sottostante per questo oggetto flusso deve essere liberato automaticamente quando viene rilasciato l'oggetto flusso. Se impostato su FALSE, il chiamante deve liberare hGlobal dopo la versione finale. Se impostato su TRUE, la versione finale libera automaticamente l'handle sottostante. Per altre informazioni sul caso in cui fDeleteOnRelease è FALSE, vedere la sezione Osservazioni.
[out] ppstm
Indirizzo della variabile puntatore IStream* che riceve il puntatore dell'interfaccia al nuovo oggetto flusso. Il valore non può essere NULL.
Valore restituito
Questa funzione supporta i valori restituiti standard E_INVALIDARG e E_OUTOFMEMORY, nonché i seguenti.
Commenti
Se hGlobal è NULL, la funzione alloca un nuovo handle di memoria e il flusso è inizialmente vuoto.
Se hGlobal non è NULL, il contenuto iniziale del flusso corrisponde al contenuto corrente del blocco di memoria. È quindi possibile usare CreateStreamOnHGlobal per aprire un flusso esistente in memoria. L'handle di memoria e il relativo contenuto non sono indisturbati dalla creazione del nuovo oggetto flusso.
Le dimensioni iniziali del flusso sono le dimensioni di hGlobal restituite dalla funzione GlobalSize . A causa dell'arrotondamento, questa non è necessariamente la stessa dimensione originariamente allocata per l'handle. Se le dimensioni logiche del flusso sono importanti, seguire la chiamata a questa funzione con una chiamata al metodo IStream::SetSize .
La posizione di ricerca iniziale del nuovo oggetto flusso è l'inizio del flusso.
Dopo aver creato l'oggetto flusso con CreateStreamOnHGlobal, chiamare GetHGlobalFromStream per recuperare l'handle di memoria associato all'oggetto flusso.
Se un handle di memoria viene passato a CreateStreamOnHGlobal o se viene chiamato GetHGlobalFromStream , l'handle di memoria di questa funzione può essere accessibile direttamente dal chiamante mentre è ancora in uso dall'oggetto flusso. È opportuno prestare attenzione nell'uso di questa funzionalità e delle sue implicazioni:
- Non liberare l'handle di memoria hGlobal durante la durata dell'oggetto flusso. IStream::Release deve essere chiamato prima di liberare l'handle di memoria.
- Non chiamare GlobalReAlloc per modificare le dimensioni dell'handle di memoria durante la durata dell'oggetto flusso o dei relativi cloni. Ciò può causare arresti anomali dell'applicazione o danneggiamento della memoria. Evitare di creare più oggetti flusso separatamente nello stesso handle di memoria, perché i metodi IStream::Write e IStream::SetSize possono chiamare internamente GlobalReAlloc. Il metodo IStream::Clone può essere usato per creare un nuovo oggetto flusso basato sullo stesso handle di memoria che coordina correttamente l'accesso con l'oggetto flusso originale.
- Se possibile, evitare di accedere al blocco di memoria durante la durata dell'oggetto flusso, perché l'oggetto può chiamare internamente GlobalReAlloc e non fare ipotesi sulle dimensioni e sulla posizione. Se è necessario accedere al blocco di memoria, le chiamate di accesso alla memoria devono essere racchiuse da chiamate a GlobalLock e GlobalUnLock.
- Evitare di chiamare i metodi dell'oggetto mentre l'handle di memoria è bloccato con GlobalLock. Ciò può causare l'esito imprevisto delle chiamate ai metodi.
L'handle di memoria passato come parametro hGlobal deve essere allocato come rimovibile e non discardibile, come illustrato nell'esempio seguente:
HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE,iSize);
if (!hMem)
AfxThrowMemoryException();
LPVOID pImage = ::GlobalLock(hMem);
... // Fill memory
::GlobalUnlock(hMem);
CComPtr<IStream> spStream;
HRESULT hr = ::CreateStreamOnHGlobal(hMem,FALSE,&spStream);
CreateStreamOnHGlobal accetterà un handle di memoria allocato con GMEM_FIXED, ma questo utilizzo non è consigliato. Gli oggetti HGLOBALs allocati con GMEM_FIXED non sono realmente handle e il relativo valore può cambiare quando vengono riallocati. Se l'handle di memoria è stato allocato con GMEM_FIXED e fDeleteOnRelease è FALSE, il chiamante deve chiamare GetHGlobalFromStream per ottenere l'handle corretto per liberarlo.
Prima di Windows 7 e Windows Server 2008 R2, questa implementazione non aveva memoria zero quando si chiama GlobalReAlloc per aumentare il blocco di memoria. L'aumento delle dimensioni del flusso con IStream::SetSize o scrivendo in una posizione oltre la fine corrente del flusso può lasciare parti della memoria appena allocata non inizializzata.
Requisiti
Client minimo supportato | Windows 2000 Professional [app desktop | App UWP] |
Server minimo supportato | Windows 2000 Server [app desktop | App UWP] |
Piattaforma di destinazione | Windows |
Intestazione | combaseapi.h |
Libreria | Ole32.lib |
DLL | Ole32.dll |