Função CreateILockBytesOnHGlobal (coml2api.h)

A função CreateILockBytesOnHGlobal cria um objeto de matriz de bytes que usa um identificador de memória HGLOBAL para armazenar os bytes destinados ao armazenamento na memória de um arquivo composto. Esse objeto é a implementação fornecida por OLE da interface ILockBytes .

O objeto de matriz de bytes retornado dá suporte à leitura e à gravação, mas não dá suporte ao bloqueio de região. O objeto chama a função GlobalReAlloc para aumentar o bloco de memória conforme necessário.

Sintaxe

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

Parâmetros

[in] hGlobal

Um identificador de memória alocado pela função GlobalAlloc ou se NULL um novo identificador deve ser alocado. O identificador deve ser alocado como movêvel e não confiável.

[in] fDeleteOnRelease

Um sinalizador que especifica se o identificador subjacente para esse objeto de matriz de bytes deve ser liberado automaticamente quando o objeto é liberado. Se definido como FALSE, o chamador deverá liberar o hGlobal após a versão final. Se definido como TRUE, a versão final liberará automaticamente o parâmetro hGlobal .

[out] pplkbyt

O endereço da variável de ponteiro ILockBytes que recebe o ponteiro de interface para o novo objeto de matriz de bytes.

Retornar valor

Essa função dá suporte aos valores de retorno padrão E_INVALIDARG e E_OUTOFMEMORY, bem como o seguinte:

Comentários

Se hGlobal for NULL, CreateILockBytesOnHGlobal alocará um novo identificador de memória e a matriz de bytes estará vazia inicialmente.

Se hGlobal não for NULL, o conteúdo inicial do objeto de matriz de bytes será o conteúdo atual do bloco de memória. Assim, essa função pode ser usada para abrir uma matriz de bytes existente na memória, por exemplo, para recarregar um objeto de armazenamento criado anteriormente pela função StgCreateDocfileOnILockBytes . O identificador de memória e seu conteúdo não são incomodados pela criação do novo objeto de matriz de bytes.

O tamanho inicial da matriz de bytes é o tamanho de hGlobal , conforme retornado pela função GlobalSize . Esse não é necessariamente o mesmo tamanho que foi originalmente alocado para o identificador devido ao arredondamento. Se o tamanho lógico da matriz de bytes for importante, siga a chamada para CreateILockBytesOnHGlobal com uma chamada para ILockBytes::SetSize.

Depois de criar o objeto de matriz de bytes com CreateStreamOnHGlobal, StgCreateDocfileOnILockBytes pode ser usado para criar um novo objeto de armazenamento na memória ou StgOpenStorageOnILockBytes pode ser usado para reabrir um objeto de armazenamento existente anteriormente que já está contido no bloco de memória. GetHGlobalFromILockBytes pode ser chamado para recuperar o identificador de memória associado ao objeto de matriz de bytes.

Se um identificador de memória for passado para CreateILockBytesOnHGlobal ou se GetHGlobalFromILockBytes for chamado, o identificador de memória dessa função poderá ser acessado diretamente pelo chamador enquanto ele ainda estiver em uso pelo objeto de matriz de bytes. A cautela apropriada deve ser exercida no uso dessa funcionalidade e suas implicações:

  • Não libere o identificador de memória hGlobal durante o tempo de vida do objeto de matriz de bytes. ILockBytes::Release deve ser chamado antes que o identificador de memória seja liberado.
  • Não chame GlobalReAlloc para alterar o tamanho do identificador de memória durante o tempo de vida do objeto de matriz de bytes. Isso pode causar falhas no aplicativo ou corrupção de memória. Evite criar vários objetos de matriz de bytes no mesmo identificador de memória, pois os métodos ILockBytes::WriteAt e ILockBytes::SetSize podem chamar internamente GlobalReAlloc.
  • Se possível, evite acessar o bloco de memória durante o tempo de vida do objeto de matriz de bytes, pois o objeto pode chamar internamente GlobalReAlloc e não fazer suposições sobre seu tamanho e localização. Se o bloco de memória precisar ser acessado, as chamadas de acesso à memória deverão ser cercadas por chamadas para GlobalLock e GlobalUnLock.
  • Evite chamar os métodos do objeto enquanto o identificador de memória estiver bloqueado com o GlobalLock. Isso pode fazer com que as chamadas de método falhem de forma imprevisível.
Se o chamador definir o parâmetro fDeleteOnRelease como FALSE, o chamador também deverá liberar o hGlobal após a versão final. Se o chamador definir o parâmetro fDeleteOnRelease como TRUE, a versão final liberará automaticamente o hGlobal. O identificador de memória passado como o parâmetro hGlobal deve ser alocado como móvel e não confiável, conforme mostrado no exemplo a seguir:
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 aceitará a memória alocada com GMEM_FIXED, mas esse uso não é recomendado. HGLOBALs alocados com GMEM_FIXED não são realmente identificadores e seu valor pode mudar quando eles são realocados. Se o identificador de memória foi alocado com GMEM_FIXED e fDeleteOnRelease for FALSE, o chamador deverá chamar GetHGlobalFromILockBytes para obter o valor HGLOBAL correto para liberar o identificador.

Essa implementação do ILockBytes não dá suporte ao bloqueio de região. Os aplicativos que usam essa implementação com as funções StgCreateDocfileOnILockBytes ou StgOpenStorageOnILockBytes devem evitar abrir várias instâncias simultâneas no mesmo objeto ILockBytes .

Antes do Windows 7 e do Windows Server 2008 R2, essa implementação não tinha memória zero ao chamar GlobalReAlloc para aumentar o bloco de memória. Aumentar o tamanho da matriz de bytes com ILockBytes::SetSize ou gravando em um local após o final atual da matriz de bytes deixará quaisquer partes não escritas da memória recém-alocada não inicializada. Os objetos de armazenamento retornados por StgCreateDocfileOnILockBytes e StgOpenStorageOnILockBytes podem aumentar o tamanho da matriz de bytes sem inicializar todo o espaço recém-alocado.

Os arquivos compostos na memória normalmente são usados como espaço zero ou com APIs que exigem um objeto de armazenamento e, nesses casos, a memória não inicializada geralmente não é uma preocupação. No entanto, se o conteúdo do bloco de memória for gravado em um arquivo, considere as seguintes alternativas para evitar a possível divulgação de informações:

  • Copie o conteúdo lógico do arquivo composto na memória para o arquivo de destino usando o método IStorage::CopyTo em vez de gravar diretamente o conteúdo do bloco de memória.
  • Em vez de um arquivo composto na memória, crie um arquivo temporário chamando StgCreateStorageEx com um valor NULL para o parâmetro pwcsName . Quando for hora de gravar no arquivo de destino, use o método IRootStorage::SwitchToFile .
  • Implemente a interface ILockBytes de modo que as realocações de memória sejam zerados (consulte, por exemplo , o sinalizador HEAP_ZERO_MEMORY em HeapReAlloc). O conteúdo da memória dessa matriz de bytes pode ser gravado em um arquivo.

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows 2000 Professional [aplicativos da área de trabalho | Aplicativos UWP]
Servidor mínimo com suporte Windows 2000 Server [aplicativos da área de trabalho | Aplicativos UWP]
Plataforma de Destino Windows
Cabeçalho coml2api.h (inclua Ole2.h)
Biblioteca Ole32.lib
DLL Ole32.dll

Confira também

GetHGlobalFromILockBytes

ILockBytes

StgOpenStorageOnILockBytes