Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.01.31;
Скачать: CL | DM;

Вниз

Транзакции в ДЛЛ   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.019 c
15-1259343501
xayam
2009-11-27 20:38
2010.01.31
SSH-клиент с автоматический входом


2-1259847059
Anastasia
2009-12-03 16:30
2010.01.31
Как передать значение функции и получить результат?


15-1259011816
Юрий
2009-11-24 00:30
2010.01.31
С днем рождения ! 24 ноября 2009 вторник


15-1259357418
Юрий
2009-11-28 00:30
2010.01.31
С днем рождения ! 28 ноября 2009 суббота


10-1163425650
Note
2006-11-13 16:47
2010.01.31
Определение наличия подключений к серверу