Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.06.2011, 09:41   #1
Alter
Старожил
 
Аватар для Alter
 
Регистрация: 06.08.2007
Сообщений: 2,183
По умолчанию Возврат значений из DLL в реальном времени

В обычном приложении можно вернуть значения в реальном времени так
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
   Tabc = procedure(A :string; B,C :Integer);

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    procedure Run(I0,I1 :Integer; V :Tabc);
    { Public declarations }
  end;

var
  Form1: TForm1;
    procedure BCall(S :string; J,K :Integer);

implementation

{$R *.dfm}

{ TForm1 }

procedure BCall(S: string; J, K: Integer);
begin
 with Form1 do
 begin
   ListBox1.Items.Add(Format('%s; %d; %d', [S, J, K]));
 end;  
end;

procedure TForm1.Run(I0, I1: Integer; V: Tabc);
var
  I :Integer;
  S :string;
begin
 for I := I0 to I1 do
 begin
   S := Format('Value: %d/%d', [I, I1]);
   if Assigned(V) then
    V(S, I, I1);
 end;  
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 Button1.Enabled := False;
  try
 Run(0, 10000, @BCall);
  finally
 Button1.Enabled := True;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 Button2.Enabled := False;
  try
 ListBox1.Items.Clear;
  finally
 Button2.Enabled := True;
  end;
end;

end.
Как сделать подобное для DLL? Что-то не придумывается.
Для такого типа Tabc = procedure(A :PChar; B,C :Integer); например.

Последний раз редактировалось Alter; 20.06.2011 в 09:49.
Alter вне форума Ответить с цитированием
Старый 20.06.2011, 10:02   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

ну а кто мешает так же воспользоватся указателем на процедуру?
параметрами такой процедуры передаваемой в dll могут быть теже типы что и в самих длл функциях.
ну а внутри этой переданой функции творите что хотите
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 20.06.2011, 17:37   #3
Alter
Старожил
 
Аватар для Alter
 
Регистрация: 06.08.2007
Сообщений: 2,183
По умолчанию

Смущает строка в параметре.

Все равно кажется, что что то не так. Или все нормально?
Пример:
DLL:
Код:
library dll0;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  SysUtils,
  Classes;

{$R *.res}

Type
  Tabc = procedure(C :PChar; A,B :Integer); stdcall;

procedure Run(I0,I1 :Integer; CallB :Tabc); stdcall;
var
  I :Integer;
begin
 for I := I0 to I1 do
 begin
   if Assigned(CallB) then
   begin
     CallB(PChar('Line ' + IntToStr(I)), I, I1);
   end;  
 end;  
end;

exports
  Run;

begin
end.
EXE:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
  
Type
  Tabc = procedure(C :PChar; A,B :Integer); stdcall;
  TRecPrc = procedure(I0,I1 :Integer; CallB :Tabc); stdcall;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    Fh :THandle;
    SucL :Boolean;
    FRun :TRecPrc;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  procedure Recp(Txt :PChar; X,Y :Integer); stdcall;

implementation

{$R *.dfm}

procedure Recp(Txt :PChar; X,Y :Integer);
var
  Buf :string;
begin
  if Assigned(Txt) then
  begin
    Buf := string(Txt);
    with Form1 do
    begin
      ListBox1.Items.Add(Format('%s; %d/%d', [Buf, X, Y]));
    end;  
  end;  
end;  

procedure TForm1.Button1Click(Sender: TObject);
begin
 Button1.Enabled := False;
  try
 If SucL then
  FRun(0, 5000, @Recp);
  finally
 Button1.Enabled := True;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 Button2.Enabled := False;
  try
 ListBox1.Items.Clear;
  finally
 Button2.Enabled := True;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Fh := 0;
 @FRun := nil;
 SucL := False;
 Fh := LoadLibrary('dll0.dll');
 If Fh <> 0 then
 begin
  @FRun := GetProcAddress(Fh, 'Run');
  if @FRun = nil then
   Exit;
  SucL := True;
 end
  else
 SucL := False;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 if Fh <> 0 then
  FreeLibrary(Fh);
 @FRun := nil;
end;

end.
Alter вне форума Ответить с цитированием
Старый 20.06.2011, 17:51   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

да в общем то нормально.

ну а строку естственно надо подправить(что вы и сделали)

Код:
@FRun := nil;
тут не надо ставить оператор взятия адреса.
Код:
if @FRun = nil then
а тут вообще делать этого нельзя, а то сравните адрес переменной(а не содержимое) FRun с nil, что всегда true.
у вас итак указательный тип.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 20.06.2011, 18:31   #5
Alter
Старожил
 
Аватар для Alter
 
Регистрация: 06.08.2007
Сообщений: 2,183
По умолчанию

Второе если делать без @ будет это




Но, если заменить на
Код:
  if not Assigned(FRun) then
   Exit;
то без ошибок.

Измененный код:
Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
 Fh := 0;
 FRun := nil;
 SucL := False;
 Fh := LoadLibrary('dll0.dll');
 If Fh <> 0 then
 begin
  @FRun := GetProcAddress(Fh, 'Run');
//  if @FRun = nil then
  if not Assigned(FRun) then
  begin
   with ListBox1.Items do
   begin
    Clear;
    Add('FRun not Assigned');
   end;
   Exit;
  end;
  SucL := True;
 end
  else
 begin
  SucL := False;
  with ListBox1.Items do
  begin
   Clear;
   Add('Not LoadLibrary');
  end
 end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 if Fh <> 0 then
  FreeLibrary(Fh);
 FRun := nil;
end;
Почему то везде не одинаковая динамическая загрузка, проверка адреса:
http://citforum.ru/programming/digest/dlldelphi.shtml
http://www.sources.ru/magazine/0804/delphidll.html
http://vsokovikov.narod.ru/New_MSDN_...untime_dll.htm


Код:
  if @FRun = nil then
и
Код:
  if not Assigned(FRun) then
одинаково верно работают, специально проверил. Так зачем усложнять?
Цитата:
а тут вообще делать этого нельзя...

Последний раз редактировалось Alter; 20.06.2011 в 22:49.
Alter вне форума Ответить с цитированием
Старый 21.06.2011, 19:43   #6
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Так зачем усложнять?
ну видимо у меня пробел в знаниях
хотя меня лично напрагяет неоднозначность кода.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Delphi (Построение графика в реальном времени) Svyazist Помощь студентам 3 02.10.2012 12:48
Какие поля отображаются в DBGrid в реальном времени? Сергей089 Компоненты Delphi 4 14.03.2011 11:51
Издеваемся над виндой в реальном времени Fainder Свободное общение 12 15.03.2010 15:22
переброс данных из Excel в Delphi в реальном режиме времени Машутка Общие вопросы Delphi 3 27.09.2008 07:19