powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Адекватность TStreamAdapter
10 сообщений из 10, страница 1 из 1
Адекватность TStreamAdapter
    #39749882
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть такой стандартный метод
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
function TStreamAdapter.Write(pv: Pointer; cb: Longint; pcbWritten: PLongint): HResult;
var
  NumWritten: Longint;
begin
  try
    if pv = Nil then
    begin
      Result := STG_E_INVALIDPOINTER;
      Exit;
    end;
    NumWritten := FStream.Write(pv^, cb);
    if pcbWritten <> Nil then pcbWritten^ := NumWritten;
    Result := S_OK;
  except
    Result := STG_E_CANTSAVE;
  end;
end;

вопрос, насколько правильна выделенная строка? Не должно ли там быть так
Код: pascal
1.
if (pv = Nil) and (cb > 0) then



Вопрос возник отсюда.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
procedure WriteBitmap(const AStrm: IStream);
var
  LBitmap: TBitmap;
  LOStrm: TStream;
begin
  LBitmap := TBitmap.Create;
  try
    // Draw bitmap
    LOStrm := TOleStream.Create(AStrm);
    try
      LBitmap.SaveToStream(LOStrm);
    finally
      LOStrm.Free;
    end;
  finally
    LBitmap.Free;
  end;
end;

var
  LFStrm: TStream;
  LIStrm: IStream;
begin
  LFStrm := TFileStream.Create('.....', fmCreate);
  LIStrm := TStreamAdapter.Create(LFStrm, soOwned);
  WriteBitmap(LIStrm);
end;

WriteBitmap COM'овский метод в другой dll

LBitmap.SaveToStream(LOStrm); вылетает с ошибкой "Неверный указатель" потому, что здесь
Код: pascal
1.
2.
3.
4.
5.
6.
procedure TBitmap.WriteStream(Stream: TStream; WriteSize: Boolean);
begin
  ............
      Stream.WriteBuffer(Colors, ColorCount * PalSize[FOS2Format]);
  ............
end;

передается массив нулевой длины.

Или ошибка здесь?
Код: pascal
1.
2.
3.
4.
function TOleStream.Write(const Buffer; Count: Longint): Longint;
begin
  OleCheck(FStream.Write(@Buffer, Count, @Result));
end;

Может должно быть так?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
function TOleStream.Write(const Buffer; Count: Longint): Longint;
begin
  if Count > 0 then
    OleCheck(FStream.Write(@Buffer, Count, @Result))
  else
    Result := 0;
end;



С уважением, Vasilisk
...
Рейтинг: 0 / 0
Адекватность TStreamAdapter
    #39749883
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_вопрос, насколько правильна выделенная строка? Не должно ли там быть так На мой вкус ее вообще не должно быть.
TStreamAdapter - просто интерфейсная прокладка, которая не должна заниматься самодеятельностью.
...
Рейтинг: 0 / 0
Адекватность TStreamAdapter
    #39749897
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если почитать первоисточник...
https://docs.microsoft.com/en-us/windows/desktop/api/objidl/nf-objidl-isequentialstream-write
pv - A pointer to the buffer that contains the data that is to be written to the stream. A valid pointer must be provided for this parameter even when cb is zero.
cb - The number of bytes of data to attempt to write into the stream. This value can be zero.

т.е. реализатор обязан адекватно реализовать методы интерфейса так, как это ожидают все.
Ничто не мешает вместо TStreamAdapter использовать свой реализатор IStream.
Точно также ничето не мешает заменить TOleStream на свой враппер над TStream
...
Рейтинг: 0 / 0
Адекватность TStreamAdapter
    #39749901
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати...
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
var
  s: IStream;
  Buf: Byte;
  sz: FixedUInt;
  Rez: HRESULT;
begin
  CreateStreamOnHGlobal(0, True, s);
  Buf := 5;
  Rez := s.Write(@Buf, 0, @sz);


CreateStreamOnHGlobal вернет в Rez S_OK т.е. все в порядке, записал 0 байт. Ошибки нет.
А по поводу массива нулевой длинны
Код: pascal
1.
2.
3.
4.
5.
6.
7.
var
  Buf: TBytes;
  ss: TStream;
begin
  SetLength(Buf, 0);
  ss := TBytesStream.Create();
  ss.WriteBuffer(Buf, 0);


Все норм, ошибок нет.
...
Рейтинг: 0 / 0
Адекватность TStreamAdapter
    #39749960
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteА по поводу массива нулевой длинны
Код: pascal
1.
2.
3.
4.
  SetLength(Buf, 0);
  // Вот тут Pointer(Buf) = nil если что.
  ss := TBytesStream.Create();
  ss.WriteBuffer(Buf, 0);
...
Рейтинг: 0 / 0
Адекватность TStreamAdapter
    #39750276
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteA valid pointer must be provided for this parameter even when cb is zero.Значит правим TOleStreamX-Cite
Код: pascal
1.
 ss.WriteBuffer(Buf, 0);


Все норм, ошибок нет.Это для TStream. Ошибка будет здесь

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
var
  Buf: TBytes;
  ss: TStream;
  ist: IStream;
begin
  SetLength(Buf, 0);
  ss := TBytesStream.Create();
  ist := TStreamAdapter.Create(ss);
  OleCheck(ist.Write(Buf, 0, nil));
end;
...
Рейтинг: 0 / 0
Адекватность TStreamAdapter
    #39750278
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извините, проблема немного не здесь
_Vasilisk_LBitmap.SaveToStream(LOStrm); вылетает с ошибкой "Неверный указатель" потому, что здесь
Код: pascal
1.
2.
3.
4.
5.
6.
procedure TBitmap.WriteStream(Stream: TStream; WriteSize: Boolean);
begin
  ............
      Stream.WriteBuffer(Colors, ColorCount * PalSize[FOS2Format]);
  ............
end;


передается массив нулевой длины.Тут массив передается ненулевой длины. Тут ColorCount = 0.

А потом нарываемся на кривую реализацию TStream.WriteBuffer в XE3
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
procedure TStream.WriteBuffer(const Buffer; Count: Longint);
var
  Buf: TBytes;
  LTotalCount,
  LWrittenCount: Longint;
begin
  SetLength(Buf, Count);  // Count = 0 => Buf = nil
  Move(Buffer, Buf[0], Count);
  { Perform a write directly. Most of the time this will succeed
    without the need to go into the WHILE loop. }
  LTotalCount := Write(Buf, 0, Count);  // передали nil

  while (LTotalCount < Count) do
  begin
    { Try to read a contiguous block of <Count> size }
    LWrittenCount := Write(Buf, LTotalCount, (Count - LTotalCount));

    { Check if we written something and decrease the number of bytes left to read }
    if LWrittenCount <= 0 then
      raise EWriteError.CreateRes(@SReadError)
    else
      Inc(LTotalCount, LWrittenCount);
  end
end;
...
Рейтинг: 0 / 0
Адекватность TStreamAdapter
    #39750323
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Хм... нафига там копирование?... В 10.2 там уже нет никакого копирования.
...
Рейтинг: 0 / 0
Адекватность TStreamAdapter
    #39750329
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpнафига там копирование? http://www.sql.ru/forum/1145705/tstream-readbuffer-writebuffer
...
Рейтинг: 0 / 0
Адекватность TStreamAdapter
    #39750356
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vavan,

Ну радует что потом они таки одумались.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Адекватность TStreamAdapter
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]