Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> DLL каким макаром можна вернуть из нее результат, может ли DLL вернуть TMemoryStream? 
V
    Опции темы
X-Vlad
Дата 9.4.2008, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 570
Регистрация: 10.4.2002
Где: Украина, Львов

Репутация: 1
Всего: 5



ActiveX - не матерится smile

Добавлено @ 14:44
Цитата

Так что одно из 2х, либо создавать временный TMemoryStream и перекачивать в него данные из aStream, или написать своего потомка от TStream который в своих функциях будет вызывать методы IStream. Т.е. в конструкторе он получит указатель на внешний IStream.


можешь на примере моего кода подсказать как это закодировать? а то я чтото не вьежаю :(

Это сообщение отредактировал(а) X-Vlad - 9.4.2008, 14:45


--------------------
Хорошая штука - комп..:)
www.x-vlad.com
PM MAIL WWW ICQ   Вверх
X-Vlad
  Дата 9.4.2008, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 570
Регистрация: 10.4.2002
Где: Украина, Львов

Репутация: 1
Всего: 5



Alexeis

вот код ДЛЛ и самой программы... можешь подправить? 
Я неработал никогда с TStreamAdapter. Сделал вот так - матерится AV

dll
Код

...
  function GetImageFromWebCam(aApplication: TApplication; const aFormCaption: string; abtnCaption: string): IStream; StdCall;

var
  frmWebCam: TfrmWebCam;

implementation

{$R *.dfm}

function GetImageFromWebCam(aApplication: TApplication; const aFormCaption: string; abtnCaption: string): IStream;
var
  aStrm: IStream;
  aStream: TStream;
begin
  Application.Handle := aApplication.Handle;
  with TfrmWebCam.Create(aApplication) do
    try
      LoadSystemCamDevice;
      Caption := aFormCaption;
      btnSnapShot.Caption := abtnCaption;
      ShowModal;
      aStream := TMemoryStream.Create;
      aStrm := TStreamAdapter.Create(aStream) as IStream;
      imgSnapShot.Picture.Bitmap.SaveToStream(aStream);
      Result := aStrm;
    finally
      Free;
    end;
end;
...


application
Код

...
procedure TForm1.LoadClick(Sender: TObject);
var
  LibHandle: THandle;
  GetImageFromWebCam: TWebCamTool;
  aOut: TStream;
  aStream: IStream;
begin
  LibHandle := LoadLibrary('webcam.dll');
  try
    if LibHandle = HINSTANCE_ERROR then
      raise EDLLLoadError.Create('Unable to Load DLL');
    @GetImageFromWebCam := GetProcAddress(LibHandle, 'GetImageFromWebCam');
    if not (@GetImageFromWebCam = nil) then begin

      aOut := TMemoryStream.Create;
      aStream := GetImageFromWebCam(Application, 'Test', 'Press Btn');
      try
        aOut := TStream(aStream);
        Image1.Picture.Bitmap.LoadFromStream(aOut);
      finally
        aOut.Free;
      end;
    end;
  finally
    FreeLibrary(LibHandle);
  end;
end;
...


помоги плз.  smile 

Это сообщение отредактировал(а) X-Vlad - 9.4.2008, 20:17


--------------------
Хорошая штука - комп..:)
www.x-vlad.com
PM MAIL WWW ICQ   Вверх
Alexeis
Дата 9.4.2008, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



X-Vlad, попробуй в приложении использовать такой класс. Его нужно создать на основе полученного IStream и дальше использовать для загрузки из потока. Этот класс свои вызовы подменит вызовами из IStream .
Код

type
  TExternStream = class(TStream)
  protected
    FSource : IStream;
    function GetSize: Int64; override;
    procedure SetSize(const NewSize: Int64); override;
  public
    constructor Create(Source : IStream);
    destructor Destroy; override;
    function Read(var Buffer; Count: Longint): Longint; override;
    function Write(const Buffer; Count: Longint): Longint; override;
    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
  end;

procedure TForm1.FormCreate(Sender: TObject);
var
  T : TStreamAdapter;
begin

end;

{ TExternStream }


constructor TExternStream.Create(Source: IStream);
begin
  inherited Create;
  FSource := Source;
end;

destructor TExternStream.Destroy;
begin
  FSource := nil;
  inherited;
end;

function TExternStream.GetSize: Int64;
var
  LastPos : LargeInt;
begin
  FSource.Seek(0, STREAM_SEEK_CUR, LastPos);
  FSource.Seek(0, STREAM_SEEK_END, Result);
  FSource.Seek(LastPos, STREAM_SEEK_SET, LastPos);
end;

function TExternStream.Read(var Buffer; Count: Integer): Longint;
begin
  if FSource.Read(@Buffer, Count, @Result) <> S_OK
  then
    Result := 0;
end;

function TExternStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
  FSource.Seek(Offset, byte(Origin), Result);
end;

procedure TExternStream.SetSize(const NewSize: Int64);
begin
  FSource.SetSize(NewSize);
end;

function TExternStream.Write(const Buffer; Count: Integer): Longint;
begin
  if FSource.Write(@Buffer, Count, @Result) <> S_OK
  then
    Result := 0;
end;



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
X-Vlad
Дата 9.4.2008, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 570
Регистрация: 10.4.2002
Где: Украина, Львов

Репутация: 1
Всего: 5



ты можешь на моем примере показать (наглядно)? извини что туплю :( Учятся как говорится по докам, книгам и чужом коде smile 

Если несложно. smile 


--------------------
Хорошая штука - комп..:)
www.x-vlad.com
PM MAIL WWW ICQ   Вверх
Alexeis
Дата 9.4.2008, 20:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



X-Vlad, у тебя ошибка тут
Код

      try
        aOut := TStream(aStream);


  Объект исполняет интерфейс, но сам интерфейс не является объектом, его можно приводить только к предку, т.е. IUnkown.

Вместо этого следует создать экземпляр TExternStream и передать ему указатель на aStream, и дальше в программе использовать экземпляр класса TExternStream.

И еще у тебя утечка в Dll тут 
Код

aStrm := TStreamAdapter.Create(aStream) as IStream;

В таком виде aStream никто не уничтожит и он осатанеться висеть в памяти, правильно будет так

Код

aStrm := TStreamAdapter.Create(aStream, soOwned) as IStream;


Добавлено через 3 минуты и 19 секунд
Цитата(X-Vlad @  9.4.2008,  19:26 Найти цитируемый пост)
ты можешь на моем примере показать (наглядно)?

Вместо 
Код

   try
        aOut := TStream(aStream);


Нужно 

Код

try
  aOut := TExternStream.Create(aStream);

..........
  aOut.Free; //Тут уничтожиться поток созданный в Dll, так как указатель на aStream занулиться. 


В остальном вроде все верно.

Добавлено через 4 минуты и 44 секунды
     aOut := TMemoryStream.Create; - тоже нужно убрать, эта строчка абсолютно лишняя.

Добавлено через 6 минут и 39 секунд
  В реализации TExternStream могут быть ошибки. Я его проверил только на синтаксис, в действии проверять долго  smile 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
X-Vlad
Дата 9.4.2008, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 570
Регистрация: 10.4.2002
Где: Украина, Львов

Репутация: 1
Всего: 5



в программе зделал вот так:
Код

    if not (@GetImageFromWebCam = nil) then begin
      aStream := GetImageFromWebCam(Application, 'Test', 'Press Btn');
      aOut := TExternStream.Create(aStream);
      try
        Image1.Picture.Bitmap.LoadFromStream(aOut);
        Image1.Refresh;
      finally
        aOut.Free;
      end;
    end;
  finally
    FreeLibrary(LibHandle);
  end;


в длл: 
Код

function GetImageFromWebCam(aApplication: TApplication; const aFormCaption: string; abtnCaption: string): IStream;
var
  aStrm: IStream;
  aStream: TStream;
begin
  Application.Handle := aApplication.Handle;
  with TfrmWebCam.Create(aApplication) do
    try
      LoadSystemCamDevice;
      Caption := aFormCaption;
      btnSnapShot.Caption := abtnCaption;
      ShowModal;
      aStream := TMemoryStream.Create;
      aStrm := TStreamAdapter.Create(aStream, soOwned) as IStream;
      imgSnapShot.Picture.Bitmap.SaveToStream(aStream);
      imgSnapShot.Picture.Bitmap.SaveToFile('c:\test.bmp'); // просто чтобы проверить что в битмапе есть картинка
      Result := aStrm;
    finally
      FSysDev.Free;
      FilterGraph.ClearGraph;
      FilterGraph.Active := false;
      Free;
    end;
end;


ничего незагружается в Image в программе. и вылетает AV на FreeLibrary(LibHandle);

в программе подключен ShareMem и в длл. Стоят первые в дпр файлах.

в чем грабли?


--------------------
Хорошая штука - комп..:)
www.x-vlad.com
PM MAIL WWW ICQ   Вверх
X-Vlad
Дата 9.4.2008, 21:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 570
Регистрация: 10.4.2002
Где: Украина, Львов

Репутация: 1
Всего: 5



ауу


--------------------
Хорошая штука - комп..:)
www.x-vlad.com
PM MAIL WWW ICQ   Вверх
Alexeis
Дата 10.4.2008, 00:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



  А ну да, есть еще одна недоработка. Когда происходит запись в поток его указатель смещается в конец. Если потом из него читать, то разумеется ничего не прочтется. Перед чтением следует установить указатель потока в нуль. 

Код

aOut := TExternStream.Create(aStream);
aOut.Position := 0;


Думаю после этого все заработает smile .


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
X-Vlad
Дата 10.4.2008, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 570
Регистрация: 10.4.2002
Где: Украина, Львов

Репутация: 1
Всего: 5



Большое спасибо. Работает. smile +1


--------------------
Хорошая штука - комп..:)
www.x-vlad.com
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0538 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.