Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.53 MB
Время: 0.025 c
2-1251196735
D1987
2009-08-25 14:38
2009.10.25
TListView


4-1220526205
Vlad Oshin
2008-09-04 15:03
2009.10.25
Не происходит сообщения WM_SETFOCUS,WM_KILLFOCUS


2-1251155492
sanx
2009-08-25 03:11
2009.10.25
Реализация списка в многопоточном приложении


2-1251642682
tonich
2009-08-30 18:31
2009.10.25
Блокировка потоков


15-1250850838
Медвежонок Пятачок
2009-08-21 14:33
2009.10.25
перечень нехорошего