Нужный механизм называется "функция обратного вызова (Callback Function)".
Отмечу, что в случае, если потом захочется переписать DLL или прогу на другом языке, лучше сразу озаботиться способом передачи параметров. В Windows API стандартной конвенцией является
stdcall.
Объявляем тип функции обратного вызова:
Код:
type
TCallbackFunc = function (...): LongBool; stdcall;
Функция с такой сигнатурой должна присутствовать в программе. Назовём её, к примеру, ProgFunc. Через указание её параметров DLL сможет запрашивать у программы любые сервисы.
Объявляем тип функции в DLL, которая будет принимать указатель на функцию обратного вызова:
Код:
TDLLFunc = function (ACallbackFunc: TCallbackFunc): LongBool; stdcall;
Эту функцию программа должна будет вызвать один раз из DLL, чтобы DLL узнала адрес функции обратного вызова. Поэтому её имя должно быть либо предопределено (например, MyCallbackInit), либо это имя должно быть где-то описано (например, в реестре при регистрации DLL). Тогда программа после загрузки DLL спокойно вызывает
Код:
type
MyCallbackInit = function (ACallbackFunc: TCallbackFunc): LongBool; stdcall;
...
//Загрузка DLL c дескриптором DllHandle
...
//Передача функции обратного вызова
MyCallbackInit := GetProcAddress(DllHandle, 'MyCallbackInit');
MyCallbackInit(ProgFunc);
и вуаля - DLL может спокойно вызывать функцию ProgFunc главной программы, указатель на которую передался в параметре ACallbackFunc.