CreateILockBytesOnHGlobal-Funktion (coml2api.h)

Die CreateILockBytesOnHGlobal-Funktion erstellt ein Bytearrayobjekt, das ein HGLOBAL-Speicherhandle verwendet, um die Bytes zu speichern, die für den In-Memory-Speicher einer zusammengesetzten Datei vorgesehen sind. Dieses Objekt ist die von OLE bereitgestellte Implementierung der ILockBytes-Schnittstelle .

Das zurückgegebene Bytearrayobjekt unterstützt sowohl Lesen als auch Schreiben, aber keine Regionssperrung. Das -Objekt ruft die GlobalReAlloc-Funktion auf, um den Speicherblock nach Bedarf zu vergrößern.

Syntax

HRESULT CreateILockBytesOnHGlobal(
  [in]  HGLOBAL     hGlobal,
  [in]  BOOL        fDeleteOnRelease,
  [out] LPLOCKBYTES *pplkbyt
);

Parameter

[in] hGlobal

Ein Speicherhandle, das von der GlobalAlloc-Funktion zugewiesen wird, oder wenn null stattdessen ein neues Handle zugewiesen werden soll. Der Handle muss als bewegliches und nicht auflösbares Element zugeordnet werden.

[in] fDeleteOnRelease

Ein Flag, das angibt, ob das zugrunde liegende Handle für dieses Bytearrayobjekt automatisch freigegeben werden soll, wenn das Objekt freigegeben wird. Wenn auf FALSE festgelegt ist, muss der Aufrufer den hGlobal nach dem endgültigen Release freigeben. Wenn auf TRUE festgelegt ist, gibt das endgültige Release den hGlobal-Parameter automatisch frei.

[out] pplkbyt

Die Adresse der ILockBytes-Zeigervariable , die den Schnittstellenzeiger auf das neue Bytearrayobjekt empfängt.

Rückgabewert

Diese Funktion unterstützt die Standardrückgabewerte E_INVALIDARG und E_OUTOFMEMORY sowie Folgendes:

Hinweise

Wenn hGlobalNULL ist, weist createILockBytesOnHGlobal ein neues Speicherhandle zu, und das Bytearray ist zunächst leer.

Wenn hGlobal nicht NULL ist, ist der anfängliche Inhalt des Bytearrayobjekts der aktuelle Inhalt des Speicherblocks. Daher kann diese Funktion verwendet werden, um ein vorhandenes Bytearray im Arbeitsspeicher zu öffnen, z. B. um ein Speicherobjekt neu zu laden, das zuvor von der StgCreateDocfileOnILockBytes-Funktion erstellt wurde. Der Speicherhandle und dessen Inhalt werden durch die Erstellung des neuen Bytearrayobjekts nicht gestört.

Die anfängliche Größe des Bytearrays entspricht der Größe von hGlobal , die von der GlobalSize-Funktion zurückgegeben wird. Dies ist nicht unbedingt die gleiche Größe, die ursprünglich aufgrund von Rundungen für den Handle zugewiesen wurde. Wenn die logische Größe des Bytearrays wichtig ist, folgen Sie dem Aufruf von CreateILockBytesOnHGlobal mit einem Aufruf von ILockBytes::SetSize.

Nach dem Erstellen des Bytearrayobjekts mit CreateStreamOnHGlobal kann StgCreateDocfileOnILockBytes verwendet werden, um ein neues Speicherobjekt im Arbeitsspeicher zu erstellen, oder StgOpenStorageOnILockBytes kann verwendet werden, um ein zuvor vorhandenes Speicherobjekt erneut zu öffnen, das bereits im Speicherblock enthalten ist. GetHGlobalFromILockBytes kann aufgerufen werden, um das Speicherhandle abzurufen, das dem Bytearrayobjekt zugeordnet ist.

Wenn ein Speicherhandle an CreateILockBytesOnHGlobal übergeben wird oder GetHGlobalFromILockBytes aufgerufen wird, kann der Aufrufer direkt auf das Speicherhandle dieser Funktion zugreifen, während es noch vom Bytearrayobjekt verwendet wird. Bei der Nutzung dieser Funktion und ihrer Auswirkungen sollte mit angemessener Vorsicht vorzugehen sein:

  • Geben Sie das hGlobal-Speicherhandle während der Lebensdauer des Bytearrayobjekts nicht frei. ILockBytes::Release muss aufgerufen werden, bevor das Speicherhandle freigegeben wird.
  • Rufen Sie GlobalReAlloc nicht auf, um die Größe des Speicherhandles während der Lebensdauer des Bytearrayobjekts zu ändern. Dies kann zu Anwendungsabstürzen oder Speicherbeschädigungen führen. Vermeiden Sie das Erstellen mehrerer Bytearrayobjekte im selben Speicherhandle, da die Methoden ILockBytes::WriteAt und ILockBytes::SetSize intern GlobalReAlloc aufrufen können.
  • Vermeiden Sie nach Möglichkeit den Zugriff auf den Speicherblock während der Lebensdauer des Bytearrayobjekts, da das Objekt möglicherweise Intern GlobalReAlloc aufruft und keine Annahmen über seine Größe und Position treffen. Wenn auf den Speicherblock zugegriffen werden muss, sollten die Speicherzugriffsaufrufe von Aufrufen von GlobalLock und GlobalUnLock umgeben sein.
  • Vermeiden Sie das Aufrufen der Methoden des Objekts, während das Speicherhandle mit GlobalLock gesperrt ist. Dies kann dazu führen, dass Methodenaufrufe unvorhersehbar ausfallen.
Wenn der Aufrufer den fDeleteOnRelease-Parameter auf FALSE festlegt, muss der Aufrufer auch den hGlobal nach dem endgültigen Release freigeben. Wenn der Aufrufer den fDeleteOnRelease-Parameter auf TRUE festlegt, gibt das endgültige Release den hGlobal automatisch frei. Das als hGlobal-Parameter übergebene Speicherhandle muss als verschiebbar und nicht auflösbar zugeordnet werden, wie im folgenden Beispiel gezeigt:
HGLOBAL	hMem = ::GlobalAlloc(GMEM_MOVEABLE,iSize);
if (!hMem)
    AfxThrowMemoryException();

LPVOID pCompoundFile = ::GlobalLock(hMem);
... // Fill memory
::GlobalUnlock(hMem);

CComPtr<ILockBytes> spLockBytes;
HRESULT hr = ::CreateILockBytesOnHGlobal(hMem,FALSE,&spLockBytes);


CreateILockBytesOnHGlobal akzeptiert Arbeitsspeicher, der mit GMEM_FIXED zugeordnet ist, aber diese Verwendung wird nicht empfohlen. HGLOBALs, die GMEM_FIXED zugeordnet sind, sind nicht wirklich Handles, und ihr Wert kann sich ändern, wenn sie neu zugeordnet werden. Wenn das Speicherhandle GMEM_FIXED zugeordnet wurde und fDeleteOnReleasefalse ist, muss der Aufrufer GetHGlobalFromILockBytes aufrufen, um den richtigen HGLOBAL-Wert abzurufen, um das Handle freizugeben.

Diese Implementierung von ILockBytes unterstützt keine Regionssperrung. Anwendungen, die diese Implementierung mit den Funktionen StgCreateDocfileOnILockBytes oder StgOpenStorageOnILockBytes verwenden, sollten das Öffnen mehrerer gleichzeitiger Instanzen für dasselbe ILockBytes-Objekt vermeiden.

Vor Windows 7 und Windows Server 2008 R2 hatte diese Implementierung beim Aufrufen von GlobalReAlloc nicht null Arbeitsspeicher, um den Arbeitsspeicherblock zu vergrößern. Durch Erhöhen der Größe des Bytearrays mit ILockBytes::SetSize oder durch Schreiben an einen Speicherort am aktuellen Ende des Bytearrays werden alle nicht geschriebenen Teile des neu zugewiesenen Arbeitsspeichers nicht initialisiert. Die von stgCreateDocfileOnILockBytes und StgOpenStorageOnILockBytes zurückgegebenen Speicherobjekte können die Größe des Bytearrays erhöhen, ohne den gesamten neu zugewiesenen Speicherplatz zu initialisieren.

Zusammengesetzte Dateien im Arbeitsspeicher werden in der Regel als Kratzspeicher oder mit APIs verwendet, die ein Speicherobjekt erfordern, und in diesen Fällen ist der nicht initialisierte Arbeitsspeicher in der Regel kein Problem. Wenn der Inhalt des Speicherblocks jedoch in eine Datei geschrieben wird, sollten Sie die folgenden Alternativen in Betracht ziehen, um eine potenzielle Offenlegung von Informationen zu vermeiden:

  • Kopieren Sie den logischen Inhalt der zusammengesetzten Datei im Arbeitsspeicher mithilfe der IStorage::CopyTo-Methode in die Zieldatei, anstatt den Inhalt des Speicherblocks direkt zu schreiben.
  • Erstellen Sie anstelle einer zusammengesetzten Datei im Arbeitsspeicher eine temporäre Datei, indem Sie StgCreateStorageEx mit einem NULL-Wert für den pwcsName-Parameter aufrufen. Wenn Sie in die Zieldatei schreiben möchten, verwenden Sie die IRootStorage::SwitchToFile-Methode .
  • Implementieren Sie die ILockBytes-Schnittstelle so, dass Speicherneuzuweisungen auf Null gesetzt werden (siehe z. B. das flag HEAP_ZERO_MEMORY in HeapReAlloc). Der Speicherinhalt dieses Bytearrays kann dann in eine Datei geschrieben werden.

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Windows 2000 Professional [Desktop-Apps | UWP-Apps]
Unterstützte Mindestversion (Server) Windows 2000 Server [Desktop-Apps | UWP-Apps]
Zielplattform Windows
Kopfzeile coml2api.h (ole2.h einschließen)
Bibliothek Ole32.lib
DLL Ole32.dll

Weitere Informationen

GetHGlobalFromILockBytes

ILockBytes

StgOpenStorageOnILockBytes