Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Адекватность TStreamAdapter / 10 сообщений из 10, страница 1 из 1
18.12.2018, 22:11
    #39749882
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Адекватность TStreamAdapter
Есть такой стандартный метод
Код: 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
18.12.2018, 22:17
    #39749883
Соколинский Борис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Адекватность TStreamAdapter
_Vasilisk_вопрос, насколько правильна выделенная строка? Не должно ли там быть так На мой вкус ее вообще не должно быть.
TStreamAdapter - просто интерфейсная прокладка, которая не должна заниматься самодеятельностью.
...
Рейтинг: 0 / 0
18.12.2018, 23:14
    #39749897
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Адекватность TStreamAdapter
Если почитать первоисточник...
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
18.12.2018, 23:32
    #39749901
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Адекватность TStreamAdapter
Кстати...
Код: 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
19.12.2018, 09:56
    #39749960
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Адекватность TStreamAdapter
X-CiteА по поводу массива нулевой длинны
Код: pascal
1.
2.
3.
4.
  SetLength(Buf, 0);
  // Вот тут Pointer(Buf) = nil если что.
  ss := TBytesStream.Create();
  ss.WriteBuffer(Buf, 0);
...
Рейтинг: 0 / 0
19.12.2018, 15:56
    #39750276
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Адекватность TStreamAdapter
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
19.12.2018, 16:00
    #39750278
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Адекватность TStreamAdapter
Извините, проблема немного не здесь
_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
19.12.2018, 16:45
    #39750323
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Адекватность TStreamAdapter
_Vasilisk_,

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

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


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