C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Приложение БД и DLL, Правильная организация...
makem
  Отправлено: 05.03.2005, 10:24


Не зарегистрирован







Доброго времени суток!
Меня интересует вопрос над которым просидел не один день. Суть вот в чем. Пишу приложение БД и для достижения модульности разбил все формы по DLL. В каждой библиотеке создаю свой датамодуль куда кладу компоненты доступа к данным. Первоначально там же находился и компонент связи с БД. Потом организовал отдельный головной датамодуль специально для доступа к базе. То есть во всех DLL остались только датамодули с компонентами типа DataSet и т.д. Таким образом получается что датасетов много, причем из разных DLL, а коннект с базой — один. Но вот связать все эти датасеты с компонентом DB получалось только при помощи включения головного датамодуля непосредственно в проект каждой DLL. Что не совсем правильно как мне кажется. Может кто подскажет как это делать по настоящему? Я где то слышал что нужно создавать пакет и ссылаться на него при построении DLL. Но каким образом это делается? И будут ли сохранены все прелести проектирования форм с компонентами БД в design-time? Спасибо ...
AVC
Отправлено: 05.03.2005, 11:12


Ветеран

Группа: Модератор
Сообщений: 1583



Могу рассказать как это сделано у меня.
Есть пакет с DataModul'ем который содержит коннект, рабочие dataset'ы общего назначения и базовый функционал. Этот пакет статический.
Формы объеденены в пакеты по сферам применения. На формах, по необходимости, DataSetы. Для правильной статической связки с сессией в момент проектирования головной DM должен быть открыт редактором Builder'a. Для динамической связки можно заполнить поле Session в конструкторе формы или где-то еще. Сказано что пакет форм использует пакет головного DM (для этого он и нужен в пакете).
Определены интерфейсные функции (точки входа), отвечающие за выполнение каких либо действий. Параметры и возврат этих функций стандартизован.
На сервере есть таблица, которая содержит информацию (в том числе) имя функции, тип функции, имя пакета где функция и какие права нужно иметь для ее вызова.
Если пользователь хочет начать действие — головной модуль читает из таблицы описание точки входа, подгружает пакет (если нужно), заполняет параметры, передает управление на точку входа. По завершении пакет освобождается и при ненадобности выгружается.
makem
Отправлено: 05.03.2005, 11:31


Не зарегистрирован







Класс... Спасибо.
Но я и понятия не имею о том как создавать пакеты и делать их статическими ...
Не убивайте, плиз... Но подскажите если не трудно. Спасибо
AVC
Отправлено: 05.03.2005, 11:45


Ветеран

Группа: Модератор
Сообщений: 1583



Я использую пакеты bpl, но это могут бать и dll.
Создается пакет File->New->Package
Статический это тот, который включен в головном приложении в список dynamic bpl
Динамический это тот который грузит само приложение методами LoadPackage / UnLoadPackage (аналог LoadLibrary / FreeLibrary). И bpl и dll в одном приложении уживаутся нормально. Главное не забыть — все что сам грузил сам и выгружай, то что грузил Borland не торгай.
makem
Отправлено: 05.03.2005, 11:53


Не зарегистрирован







А... понятно. Осталось одно. Где этот список dynamic bpl задается? Я все настройки проекта излазил чей то ничего не обнаружил... :-(
makem
Отправлено: 05.03.2005, 12:20


Не зарегистрирован







и по поводу динамической связки я не совсем догнал. Использую FIBPlus. Там такого компонента Session нет. И как заставить тот же датасет правильно ссылаться на БД во время выполнения? В дизайнтайме у меня все на ура. Спасибо.
AVC
Отправлено: 05.03.2005, 12:22


Ветеран

Группа: Модератор
Сообщений: 1583



Для приложения
Свойства Package включен чекер build with... в строке добавляю свой (руками)
Иногда можно Project-View source вставить строку
USEPACKAGE("HcDmQrb.bpi");
Обратите внимание — вставлять целиком строку, если редактировать в bpr будет записана чущь из промежуточных состояний
Или закрыть Builder и поправить bpr

Для другого пакета
В ProjectMahnager в секции Requires добавить
Для пакета правило — если влючил другой пакет, включи и то, на что он ссылается. Т.е наращивание снизу вверх.

Может понадобиться поднастроить пути к include и lib.
AVC
Отправлено: 05.03.2005, 12:26


Ветеран

Группа: Модератор
Сообщений: 1583



Session компонент, отвечающий за соединение с сервером. У вас может называться иначе.
makem
Отправлено: 05.03.2005, 12:32


Не зарегистрирован







Правильно, это компонент соединения с сервером. В моем случае TpFIBDatabase. А причем тут поле Session в конструкторе формы ?
QUOTE
Для динамической связки можно заполнить поле Session в конструкторе формы или где-то еще.

makem
Отправлено: 05.03.2005, 12:43


Не зарегистрирован







И как можно обратиться к компоненту доступа к серверу из головной формы?. Я пытался выполнить TpFIBDatabase * pDB = dmMain->fdbMain, где dmMain — это головной датамодуль а fdbMain — непосредственно компонент. В project view сделал USEPACKAGE("myname"). В отладчике на месте dmMain стоит жирный NULL! Уфффф... уже наверное замучил ....
AVC
Отправлено: 05.03.2005, 13:27


Ветеран

Группа: Модератор
Сообщений: 1583



QUOTE

А причем тут поле Session в конструкторе формы ?

Если DataSet'ы не связать с соединением в DesignTime то это удобно делать в RunTime в момент создания формы / datamodule

QUOTE

В project view сделал USEPACKAGE("myname"). В отладчике на месте dmMain стоит жирный NULL! Уфффф... уже наверное замучил ....


Я этот головной модуль создаю сам при первом вызове главной формы (наверно можно заставить это делать Borland, но лень ковыряться — и так работает) Вот код:
CODE

try
{  DM      = new TDM(Application);
   DMImg = new TDMImg(Application);
}
catch (Exception &xcp)
{ AppLocalPrms->FormaOnStart_Hide();
ShowMessage(xcp.Message + "\nOnMainFormCreate");
Application->Terminate();
}

А вот разрушать его (delete DM) не надо. Это сделает borland.
makem
Отправлено: 05.03.2005, 13:33


Не зарегистрирован







Отлично!!!!! Работает!!!! Только вот какой прикол. Если я включаю головной пакет в список Build with Runtime Packages то линкер не может связать создание головного датамодуля в конструкторе главной формы приложения. Unresolved external и все тут!!! Убрал из списка — и Ок. Может это глючок какой или как это можно понимать? Спасибо, друг , выручил biggrin.gif
AVC
Отправлено: 05.03.2005, 13:46


Ветеран

Группа: Модератор
Сообщений: 1583



Ну не знаю, может не так прописаны пути?
А может от отсутствия такого описания
class PACKAGE TDM;
class TDM : public TDataModule
Именно так. Двумя строчками
extern PACKAGE TDM *DM;

У меня он включен в список, есть USEPACKAGE, вллючен h, создаю — писал как. Использю DM--SomeMethod(..). И все строится и работает нормально.
makem
Отправлено: 05.03.2005, 13:58


Не зарегистрирован







Действительно, странно. Значит у меня что-то с головой. Ну ладно будем пробовать. Кстати а зачем ты делаешь class PACKAGE TDM; перед объявлением класса нового датамодуля? Я так понимаю что и extern PACKAGE TDM *DM; у тебя тоже остается...
makem
Отправлено: 05.03.2005, 14:11


Не зарегистрирован







Извини, я уже не на связи — убегаю. Большое спасибо. В понедельник обязательно сюда зайду. С уважением.. cool.gif
AVC
Отправлено: 05.03.2005, 14:13


Ветеран

Группа: Модератор
Сообщений: 1583



Да. У меня все эти три строки.
Если написать просто class PACKAGE TDM : public TDataModule и закрыть проект, то при следущем открытии проекта Builder преобразует DataModule к Form (глюк).
AVC
Отправлено: 05.03.2005, 14:16


Ветеран

Группа: Модератор
Сообщений: 1583



QUOTE
В понедельник обязательно сюда зайду

А я появлюсь только в среду.
Gedeon
Отправлено: 05.03.2005, 16:31


Ветеран

Группа: Модератор
Сообщений: 1742



QUOTE (AVC @ 05/03/2005, 12:16)
А я появлюсь только в среду.

И я. С праздником всех, кого это касается! biggrin.gif

Вернуться в Работа с базами данных в C++Builder