Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.10.25;
Скачать: [xml.tar.bz2];

Вниз

Как передать в 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.04 c
15-1250927746
palva
2009-08-22 11:55
2009.10.25
День Флага


11-1207080572
Lotos
2008-04-02 00:09
2009.10.25
Заполнение данных в mdvXLGrid


15-1250858767
macrodens
2009-08-21 16:46
2009.10.25
Вопрос по RAID


1-1220736884
Дмитрий Белькевич
2008-09-07 01:34
2009.10.25
Размещение файлов в Висте


10-1160553379
Alex_KV
2006-10-11 11:56
2009.10.25
Не паботает Invoke





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский