| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > взаимодействие приложения и формы в dll |
| Автор: Teleport 7.12.2008, 16:58 |
| В вопросе есть работа с бд, но сам вопрос сам по сути - о взаимодействии с dll. Потому в этом разделе. Не так давно начал делать приложения с вызовом dll, в которой есть форма. Возникла проблема. У меня в главном приложении - есть DBGrid, в котором отображаются данные из бд baza.mdb. На главной форме есть кнопка Вызов - которая отображает форму из dll. Также на главной форме есть еще кнопки 2: удалить и добавить. Они добавляют или удаляют записи в бд. В форме из dll - есть тоже DBGrid и две кнопки удалить и добавить. Так вот вопрос: как сделать так чтобы в обоих этих DBGrid одновременно отображалась информация? Т.е. - я открыл форму из dll и удалил в ней запись - тогда информация также мгновенно должна обновиться в DBGrid на главной форме. И наоборот - я открыл форму в dll и удаляю запись через главную форму - тут же должна обновится информация и в открытой форме dll в DBGrid... Прикрепляю сделанные проекты. Mainn.dpr - проект главного приложения libr.dpr - проект dll Unit1.pas- модуль формы dll Примечание: ADOConnection.Caonnected и ADOTale1.Active в проекте в инспекторе объектов поставлены в значение false. Они активизируются при событии form1.Activate. |
| Автор: THandle 7.12.2008, 17:13 |
| Teleport, ну... возможно глупая затея, но: Может быть сделать 2 сообщения, одно на удаление записи, а другое на добавление. И соответственно слать друг дружке такие сообщения и выполнять соответствующие действия? |
| Автор: Akella 7.12.2008, 17:15 |
| В библиотеке тоже создай подключение (ADOConnection и т.д.) и при вызове передавай из вызывающего приложения в библиотеку параметры подключения. Добавлено через 1 минуту и 54 секунды Т.е. работай, как будто из двух разных приложений. |
| Автор: Teleport 7.12.2008, 17:37 |
| 2 THandle - наверное, не глупая затея. Подробней мне нужно объяснить на моем примере?... 2 Akella - в библиотеке все создано! сразу создал. И что только из этого?? обновления-то не происходит одновременно... Как эти параметры подключения передать? |
| Автор: THandle 7.12.2008, 18:37 |
| Teleport, покажу просто пример. Можно вообще использовать любой тип оповещения в принципе-то. Пример с сообщениями в аттаче. |
| Автор: Teleport 7.12.2008, 19:03 | ||
2 THandle - А вот в этих строках что такое 1001 и 1003?
|
| Автор: THandle 7.12.2008, 19:53 | ||
| Teleport, цифры Это номера сообщений. http://msdn.microsoft.com/en-us/library/ms644927(VS.85).aspx
|
| Автор: Akella 7.12.2008, 20:07 |
| THandle, да ему полностью нужно учить сообщения винды и работа с dll, что толку, что мы напишем ему сейчас примеры, он же всё равно не поймёт в них ничего. Добавлено через 3 минуты и 50 секунд Как, как? А как ты что-то передаёшь в dll, так же и строку подключения передай! |
| Автор: Teleport 7.12.2008, 20:17 |
| тему считаю закрытой |
| Автор: Akella 7.12.2008, 20:19 | ||||
|
| Автор: THandle 7.12.2008, 20:24 |
Проблему то решил? Akella, что это? |
| Автор: Akella 7.12.2008, 20:39 | ||||||||
думал, что по названиям догадаетесь.
Из вызывающего приложения порядок вызова процедур плагина
Каждый плагин создаёт в главном меню вызывающего приложения свой новый пункт меню. Через этот пункт меню можно вызвать главную форму плагина Создаём новый пункт меню:
|
| Автор: Teleport 7.12.2008, 21:35 |
| 2 THandle - не решил и решу не скоро. Akella прав, мне эти примеры ни о чем просто. |
| Автор: Akella 8.12.2008, 09:43 |
| Читай, как работать с плагинами. Я по-моему взял из DRKB, точно не помню. |
| Автор: lukas 10.12.2008, 20:41 |
| Могу еще посоветовать экспортировать функции из *.exe , т.е. использовать exe как dll, для того чтобы функции нормально экспортировались из exe, их нужно поместить в *.dpr файл. Ну и вызывать нужные тебе функции в *.exe из dll. |
| Автор: Teleport 12.12.2008, 23:40 |
| 2 lukas - вот смотри, я тут немного освоил экспорт функций из dll. Вобщем если в моем основном приложении вызвать dll форму и нажать в этой форме Button3 - то изменение переменной произойдет одновременно и в dll и в основном приложении! Только вот никак не могу додуматься - как передать обновления DBGrid? Я думаю, что нужно передавать ADOTable1.Close и ADOTable1.Open - только вот как в моем примере их передать? |
| Автор: Rrader 13.12.2008, 10:34 |
| lukas, прошу, не стоит давать таких советов, грязнее метода и нет наверное Teleport, посмотрел аттач и ужаснулся. Брутфорс, и то с грубыми ошибками... Тебе же THandle предложил по сообщениям обновление организовать, это приемлемый и удобный метод. Чем не устраивает? Хотя THandle обучен еще одному эффективному методу решения подобных задач, придет, ответит |
| Автор: Teleport 13.12.2008, 12:36 |
| 2 Rrader - подробнее насчет ошибок Жду ответа. |
| Автор: Rrader 13.12.2008, 13:10 | ||||
Передача объекта - небезопасна.
Передача строки String (наверняка у тебя это AnsiString) - еще более небезопасная затея. Темы избитые, статьи можно читать разные - http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1206 и http://sources.ru/magazine/0804/delphistr.html |
| Автор: Teleport 13.12.2008, 14:43 |
| читаю про строки... |
| Автор: Teleport 14.12.2008, 14:43 |
| я немного разобрался с примером, который мне дал Thandle. И присоединил его к своей программе с бд. Все работает, но не совсем так как надо - обновления в DBGrid-ах запаздывают. Т.е. далеко не с первого клика происходят обновления. Прошу рассмотреть мой проект и сказать, как исправить чтобы обновления были с первого клика по кнопке. Mainn.dpr - проект главного приложения libr.dpr - проект dll Unit1.pas- модуль формы dll |
| Автор: Teleport 16.12.2008, 22:30 |
| проблема актуальна. Сообщения, как я понял, проходят сразу, а вот DBGrid - не обновляется сразу. Запаздыает обновления до следующего нажатия кнопки. :( в чем проблема не пойму... Какой совет может дадите? исходнике в посте выше.... :( :( |
| Автор: Teleport 20.12.2008, 20:23 |
| 2 THandle - спасибо за пример, скачал, разбираюсь. Работает. Обновляется не сразу, причем я думаю, что это дело не в самих бд... Просто вот смотри - когда с сообщениями работали - твой пример тоже, то там ведь ShowMessage - тоже невсегда с первого раза выскакивали? Все же думаю, что тут проблема в технологии передачи... Не утверждаю, конечно, но думаю, что именно так. А за интерфейсы отдельное спасибо - пытаюсь разобраться. Про с пример с сообщениями почти все понятно. Спасибо. Пытаюсь, пока безуспешно, найти решение для обновления моментального... |
| Автор: THandle 20.12.2008, 20:28 |
| Teleport, а ты во время отладки библиотеки посмотри - каждый ли раз срабатывает нужное действие. То есть отлаживай саму библиотеку. |
| Автор: Teleport 20.12.2008, 20:59 |
| хм... Как я увижу-то каждый или некаждый раз? |
| Автор: THandle 20.12.2008, 21:27 | ||
| Teleport, открываешь проект библиотеки. В Project Options, Dubugger, ставишь в Host Application нашу программу (mainn.exe или как там её). Дальше на строки:
(это в методе TExuDllInterface.Release) ставишь брякпойнты. Дальше запускаешь все это дело(Run or F9) Жмешь "Вызов". А дальше жмешь в окне программы кнопки удалить/добавить и смотришь, заходит ли в код, на котором стоят бряки. |
| Автор: Teleport 23.12.2008, 22:38 |
| спасибо, пробую)) |
| Автор: lukas 24.12.2008, 08:51 |
| Teleport, ну правильно, если ты один и тот же используешь unit и в длл и в exe, это вообще небезопасно, и не известно к каким результатам это приведет. Rrader, не знаю я пользуюсь, просто не нужно злоупотреблять таким способом. Сообщения вообще встают в очередь, а тут напрямую выполнение функции из exe. Главное знать где находиться exe, а загрузить функцию из exe можно также как и длл. Вообщем у меня еще проблем не возникало. Если могут возникнуть какие -нибудь проблемы, напишите тогда о них... мне самому интересно будет. |
| Автор: Rrader 24.12.2008, 16:07 |
| lukas, для этого придуманы интерфейсы. Затрудняюсь назвать хотя бы одно преимущество в связи EXE и DLL через экспорт из EXE по сравнению с интерфейсами. Ненужное наследство от PE-файлов |
| Автор: lukas 25.12.2008, 12:56 |
| Rrader, а разве интерфейсы не работают в разы медленнее...? |
| Автор: Rrader 25.12.2008, 13:16 |
| lukas, хотелось бы услышать обоснование |
| Автор: lukas 25.12.2008, 13:44 |
| Rrader, я конечно профессионально не смогу объяснить, но если мне не изменяет память, то перед вызовом метода интерефейса происходит куча операций, т.к. программа даже не знает куда она обращается, а при вызове функции из dll или же из exe мы один раз находим адрес функции и используем ее в дальнейшем. |
| Автор: Alexeis 25.12.2008, 14:34 | ||
Функция интерфейса вызывается также как обычная виртуальная функция, т.е. просто косвенный вызов. Фактически 2е операции 1я получение адреса по фиксированному смещению в таблице VMT интерфейса и переход по этому адресу. |
| Автор: Rrader 25.12.2008, 14:49 | ||||||||
| Alexeis, +1 Посмотрим, что же происходит.... Пишем библитоеку следующего содержания:
Здесь используются два вида связи - через экспорт и через интерфейс. Теперь пишем приложение, которое будет их вызывать.
Прямой вызов ExportFunc:
Вызов DoIt:
|
| Автор: lukas 25.12.2008, 15:36 |
| Alexeis, вопрос, этот адрес вычисляется каждый раз при вызове или как то кешируется (запоминается)? Я просто может что-то не понимаю, но как вычисляется адрес в dll функции, он вычисляется по названию 1 раз, т.е. мы нашли адрес (допустим через GetProcAddress() ), а далее при вызове мы его уже не ищем. |
| Автор: Alexeis 25.12.2008, 15:50 |
| lukas, вычисляется на лету, в этом и суть динамического связывания. Тебе что жалко одной операции сложения? |
| Автор: Teleport 27.12.2008, 15:16 |
| Вывод, вобщем, один - передача через интерфейсы. Правильно понял? |