Форум: "Прочее";
Текущий архив: 2010.01.31;
Скачать: [xml.tar.bz2];
ВнизТранзакции в ДЛЛ Найти похожие ветки
← →
acidlord (2009-11-28 13:17) [0]Добрый день всем...
Перейду сразу к делу. Веду разработку MDI приложения, где дочерние окна подгружаются как отдельные плагины в виде DLL (не пакеты). Приложение работает с БД MySQL через MyDAC (пока последней версии). Вызов и закрытие всех окон происходит перекрестно через COM интерфесы. Задача состоит в том, чтобы иметь возможность вести единую транзакцию во всех окнах приложения. Пока ничего не получается.
Сделаны следующие попытки:
1. Передача во все окна ссылки на TMyConnection. Ошибка сыпалась на вычисляемых полях (Invalid class typecast).
2. Переделал модуль данных в основном приложении на СОМ объект и передаю в DLL интерфейс на модуль данных. Ошибка пропала, но появилась такая же ошибка на dataset.fieldbyname("").value = value (именно когда fieldbyname в левой части).
Хотелось бы послушать опыт решения проблемы, если она была решена. Полазил по инету - решение предлагается для БД Interbase как передача handle-а соединения, однако у TMyConnection-а нет никаких хендлов. В общем отдаю на ваш суд. Добавлю, что все проекты DLL и основной EXE скомпилированы с включенными в них пакетами в одной версии делфи 2009.
Заранее благодарен.
← →
sniknik © (2009-11-28 15:08) [1]http://lleo.aha.ru/arhive/esse/ej/mikrowave.shtml
прочитай до конца, твой вопрос аналог самого последнего там...
← →
acidlord (2009-11-28 15:27) [2]Спасибо - это было занимательно и полезно...
Еще есть подобные бесполезные предложения?
← →
Ухарь (2009-11-28 16:24) [3]
> Полазил по инету - решение предлагается для БД Interbase
> как передача handle-а соединения, однако у TMyConnection-
> а нет никаких хендлов
В данном случае в качестве хендла можно использовать сам указатель на TMyConnection.
Единственное ограничение - плагин никогда и ни при какиз обстоятельствах не должен кастить его под TMyConnection, для него это - хендл, который передается хосту, а уже хост кастит его под TMyConnection, и выполняет запросы
← →
acidlord (2009-11-28 18:02) [4]Немного раскрою:
компонент подключения к БД один - он находится в основном приложении.
в библиотеках сидят источники данных: DATASETы, у которых connection не задан.
При создании формы из DLL я провожу назначение всем датасетам параметры коннекта примерно следующим видом:
(Components[vCounter] as TMyTable).Connection := DataModule;
где переменная DataModule - это переданный параметр из основного приложения.
Вопрос в том, что если я передаю как Pointer, то мне все равно придется сделать преобразование TMyConnection (DataModule^) или передавать как интерфейс с методом возвращающим TMyConnection вида iDataModule.GetConnection.
Вот вопрос в том, что не так не так не работает.... Вопрос, как еще может работать? Мож я не очень понял о чем речь...
← →
Ухарь (2009-11-28 18:13) [5]Так и не заработает
плагин должен быть полностью отвязан от БД, и общаться с ней через какой то прикладной интерфейс.
Ну или второй вариант - собирайте с ран-тайм пакетами, тогда можно будет передавать прямо TMyConnection
← →
acidlord (2009-11-28 18:56) [6]Если прикладной интерфейс, то получается необходимо будет выносить все датасеты в этот модуль и кроме этого реализовывать все используемые методы интерфейса... другое дело, придется тогда датасоурсы как-то подключать и не возникнет ли тут проблем таких же?
а решение №2 уже в действии (компилирую с включенными рантайм пакетами) и результат отрицательный...
Выход конечно есть: в каждой ДЛЛ сделать свое подключение и просто напросто коммитить транзацию при выходе из ДЛЛ. но это на крайний случай... хочется попробовать решить проблему... :(
← →
GDI+ (2009-11-28 19:14) [7]
> acidlord (28.11.09 15:27) [2]
>
> Спасибо - это было занимательно и полезно...
> Еще есть подобные бесполезные предложения?
Из-за архитектуры VCL его невозможно корректно в полной мере использовать в Dll. Используйте или пакеты или WinApi.
← →
acidlord (2009-11-28 19:18) [8]
> GDI+ (28.11.09 19:14) [7]
> Из-за архитектуры VCL его невозможно корректно в полной
> мере использовать в Dll. Используйте или пакеты или WinApi.
>
Это уже что-то... В общем окончательный диагноз, что решения найти не удастся?
← →
GDI+ (2009-11-28 19:23) [9]
> acidlord (28.11.09 19:18) [8]
>
> > GDI+ (28.11.09 19:14) [7]
>
> > Из-за архитектуры VCL его невозможно корректно в полной
> > мере использовать в Dll. Используйте или пакеты или WinApi.
>
> Это уже что-то... В общем окончательный диагноз, что решения
> найти не удастся?
Мне не удалось. Простейшие вещи работают, но куча глобальных объектов VCL, которые имеют свой собственный уникальный экземпляр в каждой из dll(от менеджера памяти до Application) всё портят.
В bpl все initialization / finalization для всех пакетов выполняются только один раз. И все ссылки на глобальные объекты идентичны для всего процесса.
← →
acidlord (2009-11-28 20:10) [10]Ок... спасибо за ответы... :)
← →
Суслик_ (2009-11-28 20:18) [11]зачем пользоваться dll, если пишешь обе стороны на дельфи?
я думаю, что надо пользоваться bpl.
там вообще проблем нет никаких - как будто одно монолитное приложение.
← →
Ухарь (2009-11-28 20:29) [12]
>
> а решение №2 уже в действии (компилирую с включенными рантайм
> пакетами) и результат отрицательный...
надо, чтобы передаваемый класс (TMyConnection) входил в один из этих пакетов
← →
Суслик_ (2009-11-28 21:24) [13]про пакеты, может полезно будет.
что хорошо в пакетах? это те же dll, но делают реальный монолит - как будто одно приложение. я когда-то изучал в деталях как это сделано - понял, но время все вымыло - осталось в памяти главное.
теперь о главном.
у тебя есть 2 варианта заюзать код, реализованный в пакете - грудить динамически (loadpackage) или статически (для exe значит указать в секции пакеты, выставив галку with runtime packages в опциях проекта, для пакетов - указать нужные пакеты в секции requires).
в пакетах есть одно важное правило - все деревья зависимостей без циклов, т.е. если тебе нужна общая логика для exe и пакета, то это логика должны быть либо в пакете, либо в еще одном пакете, которых заюзан статический в exe и в пакете.
теперь про реалзиацию плугинов с использованием пакетов.
делается просто:
EXE - хост приложение, которое плугинится.
INTERFACE_BPL - пакет в котором реализован интерфейс работы с плугином (родительский класс, например, хотя не обязательно, но так проще излагать).
PLUGIN_BPL - пакет с плугином.
итак, зависимости следующие:
1. EXE имеет галку run with runtime packages и в списке пакетов указан INTERFACE_BPL
2. Пакет PLUGIN_BPL имеет реализацию абстрактного интерфейса (класса) из INTERFACE_BPL. Пакет INTERFACE_BPL указан в пакете PLUGIN_BPL в списке requires. В одном из модулей из PLUGIN_BPL есть регистрация плугина, с помощью функционала, реализованного в INTERFACE_BPL.
3. EXE грузит PLUGIN_BPL с помощью LoadPackage. При этом он получает доступ к объектам из PLUGIN_BPL (они же себя зарегили при загрузке), далее работает с ними.
Это идеальный пример плугинизации - ты получаешь монолит без геморроя с памятью, разными инстансами и пр. Поверь, это очень удобно.
DLL надо пользовать в одном случае - плугины пишутся на чем-то, отличном от версии дельфи, на которой ты работаешь - это либо другая версия дельфи, или вообще другой язык.
Там вообще все просто, надо только въехать.
Вот почитай http://blog.softwarer.ru/?page_id=114
Манера автора мне не близка, но говорит дело.
← →
acidlord (2009-11-28 21:26) [14]
> Ухарь (28.11.09 20:29) [12]
>
>
> >
> > а решение №2 уже в действии (компилирую с включенными
> рантайм
> > пакетами) и результат отрицательный...
>
> надо, чтобы передаваемый класс (TMyConnection) входил в
> один из этих пакетов
А вот это мне надо проверить... как-то я об этом не подумал :)
← →
acidlord (2009-11-28 21:50) [15]проверил - все в куче... жаль....
← →
acidlord (2009-11-28 22:11) [16]В общем одно из решений, насколько я понял, это переход от ДЛЛ плагинов к БПЛ плагинам...
← →
Суслик_ (2009-11-28 22:14) [17]канечно, это единственно верное решение ))
главное понять, что у них обязательно отсутствие циклов
тут надо просто поиграть с тестовыми примерами - все поймешь.
← →
acidlord (2009-11-28 22:25) [18]Мои модули только для моего приложения - в общем спасибо... буду проект переделывать... благо, насколько я понял, переделок там немного будет... да и писать гораздо легче :) не надо передачи объектов APP и SCR во все модули и т.д. (если я все правильно понимаю)
← →
GDI+ (2009-11-28 22:29) [19]
> acidlord (28.11.09 22:11) [16]
>
> В общем одно из решений, насколько я понял, это переход
> от ДЛЛ плагинов к БПЛ плагинам...
Ну или на .NET. Там всё еще лучше. А у вас прямо нетовское приложение (Гуй и БД).
← →
Суслик_ (2009-11-28 22:49) [20]
> acidlord (28.11.09 22:25) [18]
>
> Мои модули только для моего приложения - в общем спасибо.
> .. буду проект переделывать... благо, насколько я понял,
> переделок там немного будет... да и писать гораздо легче
> :) не надо передачи объектов APP и SCR во все модули и т.
> д. (если я все правильно понимаю)
>
не факт что не много. надо четко выделить общие пакеты. т.е. надо убрать все циклические зависимости. я вот, например, так и не справился полноценно с плугинизацией - мне нужно было очень много выносить в общие пакеты, поэтому я только медленно движусь к плугинизации.
в общем, опиши интерфейсы (абстрактные классы с виртуальными методами) для плугинов, помести их в пакет, реализуй в пакете систему регистрации плугинов, статически залинкуй пакет с хост-приложением, потом создавай плугины-пакеты.
← →
Petr V. Abramov © (2009-11-28 23:20) [21]
> не надо передачи объектов APP и SCR во все модули и т.д.
> (если я все правильно понимаю)
если и у EXE, и у DLL, стоят галки, уже не надо ничего передавать.
а на DLL или на BPL делать в этом случае - по большому счету дело вкуса.
← →
Ухарь (2009-11-29 00:09) [22]
> я вот, например, так и не справился полноценно с плугинизацией
> - мне нужно было очень много выносить в общие пакеты, поэтому
> я только медленно движусь к плугинизации.
А я как то раз справился - именно на bpl-плагинах
В результате поимел так называемый DLL Hell - если после каждого чиха не пересобрать всё (хост, плагины и пакеты), то приложение постоянно подкидывает сюрпризы в виде AV.
Так что мое ИМХО - не особо хороший путь это.
← →
Игорь Шевченко © (2009-11-29 00:15) [23]Ухарь (29.11.09 00:09) [22]
> В результате поимел так называемый DLL Hell - если после
> каждого чиха не пересобрать всё (хост, плагины и пакеты),
> то приложение постоянно подкидывает сюрпризы в виде AV.
>
Кривое не может сделаться прямым (Еккл. 1,15)
← →
GDI+ (2009-11-29 00:30) [24]
> Ухарь (29.11.09 00:09) [22]
Самый прямой путь при этом - Com-automation или .NET.
Или забить на все и делать 1 Exe Файл на 7-8 Мб.
← →
Дмитрий С © (2009-11-29 06:54) [25]Я сильно не вчитывался, но все же, чем интерфейсы плохи? Написал интерфейс доступа к базе (в твоей транзакции). Реализовал его в EXE и передаешь в DLL, где и используешь. Конечно, если тебе все прелести vcl не нужны.
← →
acidlord (2009-11-29 10:42) [26]Компоненты отображения данных придется все равно в ДЛЛ размещать... А если делать что-то искусственное (не используя стандартные DBGrid), то это жесть... у меня ни времени ни мозгов не хватит, чтобы реализовывать собственный DBGrid, а иначе результата не будет...
← →
Petr V. Abramov © (2009-11-30 12:30) [27]1. EXE и DLL сбилдить с рантайм-пакетами. Application, Screen и пр. глобальные объекты никуда передать не надо.
2. Во всех юнитах в uses первым поставить sharemem
3. Во всех dll перед их выгрузкой освободить все объекты, в них созданные. Почему так надо делать, не знаю, но если не делать, на выходе будет runtime error 217.
при следовании этим простым пунктам все работает как часы, проверено на d5-d7
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2010.01.31;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.006 c