Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Как IStream перегнать в TMemoryStream?


Автор: Alca 25.6.2010, 11:20
Как IStream перегнать в TMemoryStream?

Автор: Alexeis 25.6.2010, 11:51
Создать дополнительный TStreamAdapter, который реализует IStream используя любой TStream.

Автор: Alca 25.6.2010, 11:58
а по-русски?  smile 

Автор: Alexeis 25.6.2010, 12:04
TStreamAdapter в конструкторе принимает указатель на любой объект наследник от TStream, коим является TStreamAdapter. Второй параметр определяет будет ли объект TStreamAdapter владеть переданным ему объектом (т.е. будет ответственным за его удаление). Я бы рекомендовал именно владение.

Код

DelphiInterface<IStream> IStr = new TStreamAdapter(new TMemoryStream, soOwned);


Теперь все действия производимые с IStr реально будут производиться с TMemoryStream.

Автор: Alexeis 25.6.2010, 12:26
Упс наврал.
Вот рабочий пример
Код

   DelphiInterface<IStream> IStr;
    (new TStreamAdapter(new TMemoryStream, soOwned))->QueryInterface(__uuidof(IStream), &IStr);
    int c = 5, d = 4;
    IStr->Write(&c, 4, NULL);
    IStr->Seek(LARGE_INTEGER(), STREAM_SEEK_SET, NULL);
    IStr->Read(&d, 4, NULL);


Автор: Alca 25.6.2010, 12:57
а что делать с new, Как освобождать память?

Автор: Alexeis 25.6.2010, 13:12
По идее QueryInterface увеличит счетчик ссылок, а DelphiInterface при выходе за область видимости уменьшит счетчик ссылок на единицу, после чего TStreamAdapter должен самоуничтожиться и убить TMemoryStream.

Автор: Alca 25.6.2010, 15:38
Криво, косо, но работает:
Код

BOOL bIStreamToMemoryStream(IStream *pisStream, TMemoryStream **ppmsStream) {
    /*DEBUG*/// _m_imgImage
    /*DEBUG*/xASSERT_RET(NULL !=  pisStream,  FALSE); 
    /*DEBUG*/xASSERT_RET(NULL !=  ppmsStream, FALSE);
    /*DEBUG*/xASSERT_RET(NULL != *ppmsStream, FALSE);

    HRESULT hRes = 0;

    //-------------------------------------
    //устанока размера потока ppmsStream
    STATSTG   stStat = {0};
    ULONGLONG ulSize = 0;

    hRes = pisStream->Stat(&stStat, 0);
    /*DEBUG*/xASSERT_RET(S_OK == hRes, FALSE);
    
    ulSize = stStat.cbSize.QuadPart;
    
    (*ppmsStream)->SetSize((int)ulSize);
    /*DEBUG*/// n/a
    
    //-------------------------------------
    //чтение в поток
    hRes = pisStream->Seek(LARGE_INTEGER(), STREAM_SEEK_SET, NULL);
    /*DEBUG*/xASSERT_RET(S_OK   == hRes, FALSE);
    
    ULONG ulReaded = 0;
    hRes = pisStream->Read((*ppmsStream)->Memory, ulSize, &ulReaded);
    /*DEBUG*/xASSERT_RET(S_OK   == hRes,     FALSE);
    /*DEBUG*/xASSERT_RET(ulSize == ulReaded, FALSE);

    return TRUE;
}


Alexeis, спасибо

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)