Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

реализация Callback вызова из DLL: не выходит каменный цветочек..


savva ©   (2006-11-14 19:09:00) 

Вообщем приспичило сделать DLL которой передается указатель на процедуру, которую надо вызвать в нужный момент (кодом из DLL). Ну че то у меня не выходит.
основные моменты:

var
 callBackProc: TFarProc; // указатель на нужную процедуру

procedure initCBPointer(p: Pointer); stdcall; external 'testDLL';// утанавливает указатель на нужную процедуру
procedure TestCall; stdcall; external 'testDLL'; // просто для проверки

procedure testProc(const p: Pchar); { это вызываемая процедура }
begin
 ShowMessage(StrPas(p));// до сюда даже не доходит:)
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 callBackProc := MakeProcInstance(@testProc, hInstance);
 initCBPointer(callBackProc); // инициализируем
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 FreeProcInstance(callBackProc);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 TestCall; // вызываем
end;

соответственно код DLL

type
 PCallbackProc = ^TCallbackProc;
 TCallbackProc = procedure(p :PChar);stdcall;

var
 saveCBProc : PCallbackProc;

 
procedure initCBPointer(cbProc: Pointer); stdcall;
begin
 saveCBProc := cbProc;
end;

procedure TestCall; stdcall;
var
 tmp : Pchar;
begin
 getMem(tmp, 4);
 try
   StrPCopy(tmp,'test');
   saveCBProc^(tmp);
 finally
   FreeMem(tmp);
 end;
end;


ЗЫ. Вот уж не думал что спрошу на эту тему. Стыдно, млин:)
ЗЫЫ. исходники тестового проекта http://www.webfile.ru/1191680


Eraser   (2006-11-15 00:42:00) [1]

> [8] savva ©   (14.11.06 22:13)


> Спасибо  большое...

не за что!

ну в принципе, там почти все правильно было, чтобы использовать код как есть можно просто заменить

> saveCBProc^(tmp);

на
TCallbackProc(saveCBProc)(tmp);
только, опять же, в чем тогда тайный смысл использования типизированного указателя, когда он используется как нетипизировнный ))


savva   (2006-11-14 22:13:00) [2]

да уж:) веки живи, век учись - дураком помрешь:)

Спасибо  большое...

ЗЫ. придется заново начинать процесс самообучения по части указателей:)


Eraser   (2006-11-14 21:04:00) [3]

ЗЫ
потестил с

> procedure initCBPointer(cbProc: Pointer); stdcall;
> begin
> New(saveCBProc);
> saveCBProc^ := cbProc;
> end;

и без PCallbackProc вообще - прекрасно работает.

ЗЗЫ
не забудьте раставить где надо stdcall.


Eraser   (2006-11-14 21:02:00) [4]

> [5] savva ©   (14.11.06 20:05)
> выполняется.. а что криминального в таком определении?

скорее всего то, что если уж так делать,
то нужно вместо

> procedure initCBPointer(cbProc: Pointer); stdcall;
> begin
> saveCBProc := cbProc;
> end;

писать
procedure initCBPointer(cbProc: Pointer); stdcall;
begin
 New(saveCBProc);
 saveCBProc^ := cbProc;
end;

а вообще лучше убрать эти заморочки с указателями, лишнее никому не нужно нагромаждение.


savva   (2006-11-14 20:05:00) [5]

выполняется.. а что криминального в таком определении?


Eraser   (2006-11-14 19:56:00) [6]

> [2] savva ©   (14.11.06 19:50)

нет, тут не в системе дело.

>   saveCBProc^(tmp);

"^" возможно здесь и ошибка, лучше не использовать PCallbackProc.
код до туда и после выполняется?


savva   (2006-11-14 19:51:00) [7]

попробуй прогнать тестовый проект, а?


savva   (2006-11-14 19:50:00) [8]

>> Eraser ©   (14.11.06 19:46) [1]
изначально так все и было - перестраховался, ибо не выходило..
stdcall было и убирал..

ЗЫ. Возможно имеет смысл объявить ОС: WinXP, Win2003 Server


Eraser   (2006-11-14 19:46:00) [9]

> callBackProc := MakeProcInstance(@testProc, hInstance);

лишнее. достаточно initCBPointer(@callBackProc);

> procedure testProc(const p: Pchar); { это вызываемая процедура
> }
> begin
> ShowMessage(StrPas(p));// до сюда даже не доходит:)
> end;

должна быть объявлена как stdcall, судя по логике программы.

> FreeProcInstance(callBackProc);

лишнее.


Наверх

Титульная страница Поиск, карта сайта Написать письмо