Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
2-1260335500
ArtemSTR
2009-12-09 08:11
2010.01.31
Нужна помощь


15-1259489854
koha!
2009-11-29 13:17
2010.01.31
А что так дорого стоит RAD Studio?


1-1234886728
Drowsy
2009-02-17 19:05
2010.01.31
DLL BCB из Дельфи


3-1234091593
Booo
2009-02-08 14:13
2010.01.31
Ошибка


2-1260337028
Леонид Артюхов
2009-12-09 08:37
2010.01.31
Как наложить одну картинку на другую?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский