Microsoft DirectX 9.0

Loading an Object from a Resource or Memory Address

Objects stored as resources or at some other location in memory are loaded in much the same way as file objects. See Loading an Object from a File.

With memory objects, however, the wszName, guidObject, and wszFileName members of the DMUS_OBJECTDESC structure are irrelevant. Instead, you must obtain a pointer to the block of memory occupied by the object, and its size, and put these in the pbMemData and llMemLength members respectively. You must also set the DMUS_OBJ_MEMORY flag in the dwFlags member.

After IDirectMusicLoader8::GetObject has been called on an object in memory, the address and size of the memory buffer are privately cached by the loader. If you then release the buffer, a subsequent memory allocation might use the same address, and when another object is loaded from that address, the cached memory size will be used, possibly resulting in an incorrect number of bytes being loaded. To prevent this from happening, after loading the first object call IDirectMusicLoader8::SetObject with the same DMUS_OBJECTDESC descriptor, but with NULL in pbMemData. For this to work, the object descriptor must contain a name or GUID when passed to both GetObject and SetObject.

Note   It is usually best not to release or change the contents of memory from which an object has been loaded, because it is difficult to be sure that the loader will not need to access the data again. In most cases, you should not release or reuse memory until after the loader is released. Also, do not load objects from data passed on the stack.

The following function loads a MIDI file from a resource into a segment:

HRESULT LoadMidi(HMODULE hMod, WORD ResourceID, 
                 IDirectMusicLoader8* pLoader, IDirectMusicSegment8** ppSeg)
  HRESULT      hr;
  HRSRC hFound = FindResource(hMod, MAKEINTRESOURCE(ResourceID), RT_RCDATA);
  HGLOBAL hRes = LoadResource(hMod, hFound);
  if (NULL == hRes) return E_FAIL; 
  objDesc.dwSize = sizeof(DMUS_OBJECTDESC);
  objDesc.guidClass = CLSID_DirectMusicSegment;
  objDesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_MEMORY;
  objDesc.pbMemData = (BYTE *) LockResource(hRes);
  objDesc.llMemLength = SizeofResource(hMod, hFound);
  if (pLoader && ppSeg)
    hr = pLoader->GetObject(
        &objDesc, IID_IDirectMusicSegment8, 
        (void**) ppSeg);
    return hr;
  else return E_INVALIDARG;  

Objects referenced by other objects must be loaded first. For example, if you load a segment that contains a reference to a style, the style must already be loaded in order for the segment to play correctly. Alternatively, you can call IDirectMusicLoader8::SetObject on the style so that the segment can find it.

See Also