![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
реализация 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);
лишнее.