Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Прогресс от DLL в TEdit


Автор: Desperate 8.11.2018, 23:15
Всем привет! 
Уже сломал всю голову, вопрос вот в чем, 
в DLL есть простейшая процедура

procedure MyProc;
var i:integer;
begin
    for i:= 0 to 1000 do begin
        
         Sleep(10);
    end;
end;

В приложении вызываю процедуру и нужно каждую итерацию (i) отображать в TEdit.

пробовал параметром передать 
procedure MyProc(out str:string);
....
str:=inttostr(i);
...

ругается. 

Как можно реализовать?
Спасибо.

Автор: Hiori 9.11.2018, 09:24
а передать в исполняемую процедуру собственно edit Вы не хотите?
аля 
Код
function MyProc(AObject: TObject): Boolean;

и потом вызывать подпихивая ей уже существующий на форме компонент
Код
MyProc( MyEdit );


Автор: Snowy 9.11.2018, 12:59
Если нужно передать число, то и передавай число. Зачем строку?
Если так уж нужно передавать именно текст, то используй PChar.
У dll собственный менеджер памяти и гонять между dll и приложением сложные объекты - плохая затея.
Нужно использовать примитивные или простые блоки данных.
String, а тем более TEdit к ним не относится.
Если так уж хочется гонять сложные объекты, то лучше использовать bpl, а не dll

Автор: Desperate 9.11.2018, 13:17
Snowy, я то не против, но задание данное мне гласит:
отображать каждое изменение (i) dll в TEdit на форме вызывающего приложения.

Как передать в процедуру DLL это понятно.
Как вернуть ИТОГОВЫЙ результат функции из DLL понятно.
А вот как возвращать каждое приращение в Edit(аля Прогресс). Вот тут и проблемка возникла. 
Текстовый результат т.к. предположил по причине того что Edit.Text хавает только текст.

Возможно есть вариант пробросить число с последующим его отображением в Edit?

Автор: Snowy 9.11.2018, 14:38
То есть проблема в том, что тебе нужно из dll вызывать функцию в приложении?
Ну это можно сделать через callback или отправкой сообщений в основную форму.

В приложении и dll описываешь колбэк:
Код
type
  TCallBackInt = procedure(i: Integer);


В dll делаешь параметр типа колбэк:
Код
procedure MyProc(callback: TCallBackInt);
var
  i: Integer;
begin
  for i := 0 to 100 do begin
    callback(i);
    Sleep(10);
  end;
end;


Приложении реализуешь действия по колбэку:
Код

procedure CallBackInt(i: integer);
begin
  Form3.Edit1.Text := IntToStr(i);
  Application.ProcessMessages;
end;

procedure TForm3.Button1Click(Sender: TObject);
begin
  MyProc(CallBackInt);
end;


Автор: Desperate 9.11.2018, 15:03
Ооо.  smile  
Похоже на истину. Вечерком попробую smile 
Спасибо. О таком варианте применения даже не подозревал.

Верно понимаю такой подход (объявление в типе процедуры) называется CallBack'ом?

Автор: Snowy 9.11.2018, 16:55
Да. Callback - это функция для обратного вызова. 
Как раз используется для реакций вызывающего на какие-либо действия.
Посмотри в википедии там подробнее расписано.

Автор: Desperate 9.11.2018, 17:00
Цитата(Snowy @ 9.11.2018,  16:55)
Да. Callback - это функция для обратного вызова. 
Как раз используется для реакций вызывающего на какие-либо действия.
Посмотри в википедии там подробнее расписано.

Благодарю.

Уже  нагуглил инфы.  smile 
До этого не знал как правильно обозвать механизм и ничего толком найти не мог

Автор: Desperate 10.11.2018, 05:50
Цитата(Snowy @ 9.11.2018,  14:38)
Код

procedure CallBackInt(i: integer);
begin
  Form3.Edit1.Text := IntToStr(i);
  Application.ProcessMessages;
end;

procedure TForm3.Button1Click(Sender: TObject);
begin
  MyProc(CallBackInt);
end;

Блин, упирается в строчку 
MyProc(CallBackInt);
Ошибка Incompatible types:"Calling conventions differ"
 smile 

Автор: Desperate 12.11.2018, 02:05
Цитата(Snowy @ 9.11.2018,  14:38)
То есть проблема в том, что тебе нужно из dll вызывать функцию в приложении?
Ну это можно сделать через callback или отправкой сообщений в основную форму.

В приложении и dll описываешь колбэк:
Код
type
  TCallBackInt = procedure(i: Integer);


В dll делаешь параметр типа колбэк:
Код
procedure MyProc(callback: TCallBackInt);
var
  i: Integer;
begin
  for i := 0 to 100 do begin
    callback(i);
    Sleep(10);
  end;
end;


Приложении реализуешь действия по колбэку:
Код

procedure CallBackInt(i: integer);
begin
  Form3.Edit1.Text := IntToStr(i);
  Application.ProcessMessages;
end;

procedure TForm3.Button1Click(Sender: TObject);
begin
  MyProc(CallBackInt);
end;

Все. Вопрос решен. Заработало smile 

По коду маааленькая правочка
В приложении и dll описываешь колбэк:
Код
type
  TCallBackInt = procedure(i: Integer) of object;


И после этого делфя собрала проект.

Автор: Snowy 12.11.2018, 14:27
of object нужен в том случае, если это не процедура, а метод объекта (формы).
Если он сам по себе, то не нужно.

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