Текущий архив: 2009.10.25;
Скачать: CL | DM;
ВнизКак передать в dll адрес процедуры?.. Найти похожие ветки
← →
Franzy (2009-08-31 13:39) [0]Обсуждение было закрыто, хотя еще не все понятно. Процитирую:
Franzy (31.08.09 13:04)
У меня программная библиотека (dll) делает расчеты, порой весьма времяемкое. Теперь хочу сделать так, чтобы библиотека могла как-нибудь сообщать прогресс выполнения (например, в процентах). Т.е. нужен некий механизм "вещания в эфир" (поскольку библиотека не знает, кто ее будет вызывать). Для этого можно использовать мессаджи виндоуз или что-то еще?
stas © (31.08.09 13:17) [1]
можно передавать адрес процедуры, которая будет вызываться в момент продвижения прогресса допустим на 1%, либо в нее будет засыалаться параметр % прогресса.
<Цитата>
stas © (31.08.09 13:18) [2]
т.е. твоя функция должна принимать адрес процедуры и вызывать ее в нужном месте.
----------------------------
Так как передавать в dll адрес процедуры? Dll и основная программа написаны на разных языках.
← →
Медвежонок Пятачок © (2009-08-31 13:40) [1]так же как и любой другой параметр
← →
Сергей М. © (2009-08-31 14:02) [2]
> как передавать в dll адрес процедуры
Надо понимать, с передачей адреса процедуры не в dll у тебя проблем не возникает ?
← →
stas © (2009-08-31 15:00) [3]MoyaProceduraIzDll (@MoyaProceduraIzProgramy)
← →
stas © (2009-08-31 15:01) [4]Это если вызов на delphi
← →
Franzy (2009-08-31 15:57) [5]Я просто никогда раньше этого не делал. Т.е. с процедурами можно так же как и с переменными? Не знал.
← →
Медвежонок Пятачок © (2009-08-31 15:58) [6]что, ни разу свойству-событию не присваивал адрес обработчика?
← →
Franzy (2009-08-31 15:59) [7]Тут есть один минус в плане обратной совместимости. Ведь если такой процедуры нет в головной программе, будет вылет... Склоняюсь к мысли организовать пайп.
← →
stas © (2009-08-31 16:04) [8]Franzy (31.08.09 15:59) [7]
можно Nil передавать вмето адреса, а в dll его обрабатывать.
← →
Медвежонок Пятачок © (2009-08-31 16:06) [9]Ведь если такой процедуры нет в головной программе
Как же было страшно писателю TButton"а, когда он думал, а вдруг программист на ОнКлик никакого обработчика не повесит.
← →
Сергей М. © (2009-08-31 16:07) [10]
> если такой процедуры нет в головной программе, будет вылет
Зачем же подсовывать фуфло вместо реального адреса реально существующей процедуры ?
> Склоняюсь к мысли организовать пайп
Ядреной бомбой по воробьям ?)
← →
Юрий Зотов © (2009-08-31 16:08) [11]> Franzy (31.08.09 13:39)
Этот прием назвается "обратный вызов" (callback). При вызове функции мы передаем ей адрес другой функции и первая, когда ей надо, сама вызывает вторую. Такой механизм часто используется, например, функциями WinAPI. Заметьте, что эти функции написаны на C, но, тем не менее, запросто вызываются програмой Delphi и сами запросто вызывают дельфишный же callback - так что нет разницы, на каких языках все эти функции написаны, важно лишь, чтобы было соблюдены соглашения о вызове (см. в справке тему "Calling conventions").
1. Сначала определяем прототип callback-функции, например:type
TMyCallbackProc = procedure(ProgressPosition: integer); stdcall;
Этот прототип должен быть известен и в EXE (для того, чтобы там эту функцию правильно написать), и в DLL (для того, чтобы ее оттуда правильно вызвать).
2. Функция DLL может иметь сколько угодно любых параметров, но среди них обязан быть один параметр типа TMyCallbackProc, например:procedure MyDLLProc(..., Callback: TMyCallbackProc); stdcall;
3. Внутри функции MyDLLProc можно в любой момент вызвать callback-функцию в соответствии с ее прототипом, например:
CallBack(85);
4. Реализуем callback-функцию в EXE, например:procedure MyCallbackProc(ProgressPosition: integer); stdcall;
begin
... // Обновляем ProgressBar
end;
5. Теперь все готово - вызываем из Exe функцию DLL, передавая ей адрес callback-функции:MyDLLProc(..., @MyCallbackProc);
← →
Franzy (2009-08-31 16:14) [12]Спасибо за обстоятельный ответ.
Тем не менее, насколько я понял, использование колбека подразумевает изменение кода и dll, и всех exe (и новой, и старых, тоже использующих эту dll), что мне не очень подходит. Хотелось бы сохранить полную обратную совместимость.
← →
Медвежонок Пятачок © (2009-08-31 16:17) [13]менять код придется везде в любом случае при любом избранном способе "вещания"
← →
Медвежонок Пятачок © (2009-08-31 16:20) [14]А вообще угораю я над кадрами.
Приходит спрашивающий, задает вопрос.
ПРиходит мастер, все разжевывает и кладет в клювик (поцеловать только забыл)
На что спрашивающий отвечает: все это конечно хорошо, но мне это не подходит.
← →
Сергей М. © (2009-08-31 16:23) [15]
> сохранить полную обратную совместимость
Каким образом модификация Dll, подразумевающая новую, доселе нефигурировавшую процедуру и никак не затрагивающая доселе фигурировавшие, может повлиять на обратную совместимость ?
← →
Медвежонок Пятачок © (2009-08-31 16:26) [16]Ну как как?
Сказано же модное - пайп!
:)
← →
Сергей М. © (2009-08-31 16:27) [17]
> модное - пайп!
Сейчас моднее через блютуз почтой обмениваться)
← →
Юрий Зотов © (2009-08-31 16:31) [18]> Franzy (31.08.09 16:14) [12]
> использование колбека подразумевает изменение кода и dll, и всех exe (и
> новой, и старых, тоже использующих эту dll), что мне не очень подходит.
> Хотелось бы сохранить полную обратную совместимость.
Потребовалась НОВАЯ функциональность - оповещение о позиции прогрессбара. Спрашивается - каким волшебным способом можно реализовать эту НОВУЮ функциональность, НЕ МЕНЯЯ кода Exe и DLL?
Любой способ все равно потребует изменения кода. Чудес не бывает.
← →
Franzy (2009-08-31 16:59) [19]Вы не поняли. Есть длл, которая проводит некий расчет. Алгоритм расчета постоянно улучшается, но при этом интерфейс общения длл с программой остается прежним. Программ, использующих эту длл, на текущий момент уже несколько, причем написаны они на разных языках. Обновлять их все при изменении интерфейса будет проблематично.
Я хочу улучшить длл так, чтобы она могла отчитываться о прогрессе расчета. Пока что придумал такой способ: расширить интерфейс, добавив в него альтернативный вызов расчетной процедуры (с коллбеком). Таким образом сохраняется и обратная совместимость, и появляются новые возможности.
Всем спасибо (особенно Юрию Зотову), проблема, кажется, решена.
← →
Сергей М. © (2009-08-31 17:01) [20]
> расширить интерфейс, добавив в него альтернативный вызов
> расчетной процедуры (с коллбеком). Таким образом сохраняется
> и обратная совместимость, и появляются новые возможности
Вполне логичное решение.
← →
Franzy (2009-09-01 13:14) [21]Кстати, а можно как-то глобальный алиас процедуры создать? А то у меня в длл интерфейсная функция - это всего лишь обертка и все расчетные процедуры вызываются уже из нее. Соответственно, насколько я понимаю, коллбек в них будет недоступен. Это обстоятельство можно как-то забороть?
← →
Franzy (2009-09-01 13:17) [22]Можно :) Нужно только глобальную переменную соотв. типа объявить. Вопрос снят.
← →
Сергей М. © (2009-09-01 13:19) [23]
> коллбек в них будет недоступен
Не то что недоступен - они вообще знать не знают ни о каких колбэках, ибо писались он тобой до того как тебе пришло в голову организовать дополнительную колбэк-функциональность.
← →
Franzy (2009-09-01 13:46) [24]Ну, я просто ввел глоб. переменные DoReport: boolean и Rep : TCallbackReport. Плюс объявил процедуру
procedure SitRep(s: string)
if DoReport then rep(s);
End;
А в альтернативной интерфейсной функции написал
rep := CallBackReport;
DoReport:=true;
Ну и добавил в нужных местах вызовы SitRep в самой расчетной процедуре. Все работает при любых вызовах, и старом, и новом.
← →
Медвежонок Пятачок © (2009-09-01 13:50) [25]молодец. стройная, грациозная конструкция из кучи подпорок
Страницы: 1 вся ветка
Текущий архив: 2009.10.25;
Скачать: CL | DM;
Память: 0.51 MB
Время: 0.051 c