Здравствуйте, Kirill Bezrukov, Вы писали:
KB>Пакет загружается статически, при ShowModal выдается ошибка. И даже при ShowMessage. KB>Что не так делаю?
KB>
..........
KB>
Я что-то не понял. А зачем exports? Почему не uses?
unit UnitInPackage;
interface
function ShowForm(ADataSet: TDataSet): boolean;
implementation
function ShowForm(ADataSet: TDataSet): boolean;
begin
ADataSet.Open;
Form1 := TForm1.Create(Application);
try
Form1.DataSource1.DataSet := ADataSet;
Result := Form1.ShowModal = IDOK;
finally
Form1.Free;
end;
end;
{$R *.dfm}end.
И дальше:
uses UnitInPackage;
...........
ShowForm(...)
Только поставить опцию --- Build with package unit, куда включить RTL, VCL, и пакет для работы с БД.
Здравствуйте, Mystic, Вы писали:
M>Здравствуйте, Kirill Bezrukov, Вы писали:
KB>>Пакет загружается статически, при ShowModal выдается ошибка. И даже при ShowMessage.
M>Я что-то не понял. А зачем exports? Почему не uses?
>>Build with package unit
Это делать не хотелось, т.к. надо настройки проекта править... Надо, чтобы пакет подключался как обычная DLL либо динамически, либо статически.
Смысл в том, чтобы это все разные люди независимо разрабатывали (не видя код друг друга) и был юнит интерфейсов функций, который подключен к основной программе. Т.е. при подключение минимальное число действий производится.
Вообще в с пакетами так можно работать, через exports ?
Здравствуйте, Kirill Bezrukov, Вы писали: KB>Смысл в том, чтобы это все разные люди независимо разрабатывали (не видя код друг друга) и был юнит интерфейсов функций, который подключен к основной программе. Т.е. при подключение минимальное число действий производится.
Ну все правильно. Вон компоненты же разрабатывают люди независимо от борланда? И никаких экспортов там нет.
Короче, делается это вот таким примерно образом:
1. Делаем юнит, в котором объявлены необходимые интерфейсы. Как правило, проще всего работать с абстрактным классом или несколькими классами.
2. Помимо декларации этого абстрактного класса, делаем в этом же юните механику регистрации классов-наследников. Аналогично RegisterClass/FindClass.
3. Все это добро выносится в отдельный пакет.
4. Теперь у нас есть две команды: одна разрабатывает "потребителя" (приложение), другая "поставщика" (пакет)
5. Первая команда реализует логику поиска и загрузки пакетов через LoadPackage, а потом использование зарегистрированных классов. Благодаря наличию общего абстрактного предка со всеми можно работать примерно одним и тем же образом. Ясен перец, что приложение пользует зарегистрированные классы через общий пакет (см. п.3.)
6. Вторая команда реализует пакет, который зависит от общего пакета. В initialization/finalization юнитов выполняется работа по регистрации/дерегистрации классов (см. п.2).
Теперь при статической линковке все юниты (из приложения, из общего пакета, и из пакетов-плугинов) встраиваются прямо унутрь exe и все работает само. При use runtime packages код раскидывается по bpl.
Пример такого приложения опубликован на RSDN.
KB>Вообще в с пакетами так можно работать, через exports ?
Не нужно.
... << RSDN@Home 1.1.3 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>5. Первая команда реализует логику поиска и загрузки пакетов через LoadPackage, а потом использование зарегистрированных классов. Благодаря наличию общего абстрактного предка со всеми можно работать примерно одним и тем же образом. Ясен перец, что приложение пользует зарегистрированные классы через общий пакет (см. п.3.) S>6. Вторая команда реализует пакет, который зависит от общего пакета. В initialization/finalization юнитов выполняется работа по регистрации/дерегистрации классов (см. п.2).
Эту схему я знаю... В ней мне не нравиться один момент, что для каждого вида модулей (я не про плагины говорю с одинаковым интерфейсом) должен быть дополнительный пакет абстрактных классов...
Например: в одном пакете храниться грид, для отображения DataSet; в другом алгорим расчета; в третьем фреймы для редактирования объектов предметной области... Если действовать по вышеуказанной схеме, то либо делать один абстрактный пакет в котором будут находиться абтрактные классы для всех перечисленных пакетов (не хотелось, чтобы они зависели друг от друга) , либо на каждый пакет делать свой отдельный абстрактный пакет (тоже не хотелось бы)
Для клиента использующего эти пакеты было бы удобно просто вызвать функцию:
ExecGridForm(ADataSet), как мне кажется...
Если в общих чертах, мне надо DLL в которую можно нормально передавать строки и объекты(компоненты) но не исмопльзую SharedMem...
Здравствуйте, Kirill Bezrukov, Вы писали:
KB>Эту схему я знаю... В ней мне не нравиться один момент, что для каждого вида модулей (я не про плагины говорю с одинаковым интерфейсом) должен быть дополнительный пакет абстрактных классов... KB>Например: в одном пакете храниться грид, для отображения DataSet; в другом алгорим расчета; в третьем фреймы для редактирования объектов предметной области... Если действовать по вышеуказанной схеме, то либо делать один абстрактный пакет в котором будут находиться абтрактные классы для всех перечисленных пакетов (не хотелось, чтобы они зависели друг от друга) , либо на каждый пакет делать свой отдельный абстрактный пакет (тоже не хотелось бы)
А тогда зачем тебе вообще какие-то интерфейсы??? Если у тебя все модули разные — просто выноси их в отдельный пакет, а в программе так и пиши — uses. Этот uses автоматически превратится в подгрузку DLL при необходимости. KB>Для клиента использующего эти пакеты было бы удобно просто вызвать функцию: KB>ExecGridForm(ADataSet), как мне кажется...
KB>Если в общих чертах, мне надо DLL в которую можно нормально передавать строки и объекты(компоненты) но не исмопльзую SharedMem...
Это и есть BPL.
... << RSDN@Home 1.1.3 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Kirill Bezrukov, Вы писали:
KB>В общем у меня такой код, и он почему-то не работает... Сам отладить не могу, тольку не хватает, но очень хочется, чтобы это работало:
Кирилл, тебе же говорят — не надо так делать. Ты делаешь ненужную и вредную работу. Добрые дяди из борланд все сделали за тебя.
В программе просто сделай uses на этот юнит и вызывай функцию ExecForm напрямую. В опциях проекта включи галку use runtime packages и не забудь указать имя своего пакета в списке. И будет тебе счастье с большой буквы с.
... << RSDN@Home 1.1.3 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Кирилл, тебе же говорят — не надо так делать. Ты делаешь ненужную и вредную работу. Добрые дяди из борланд все сделали за тебя. S>В программе просто сделай uses на этот юнит и вызывай функцию ExecForm напрямую. В опциях проекта включи галку use runtime packages и не забудь указать имя своего пакета в списке. И будет тебе счастье с большой буквы с.
Да, так все работает, только приходится еще и dcp тащить вместе с bpl...
А если загрузка динамичекая, как с экспортируемыми функциями работать?
Здравствуйте, Kirill Bezrukov, Вы писали:
KB>Здравствуйте, Sinclair, Вы писали:
S>>Кирилл, тебе же говорят — не надо так делать. Ты делаешь ненужную и вредную работу. Добрые дяди из борланд все сделали за тебя. S>>В программе просто сделай uses на этот юнит и вызывай функцию ExecForm напрямую. В опциях проекта включи галку use runtime packages и не забудь указать имя своего пакета в списке. И будет тебе счастье с большой буквы с.
KB>Да, так все работает, только приходится еще и dcp тащить вместе с bpl...
KB>А если загрузка динамичекая, как с экспортируемыми функциями работать?
Здравствуйте, s.ts, Вы писали:
ST>Здравствуйте, Kirill Bezrukov, Вы писали:
KB>>Здравствуйте, Sinclair, Вы писали:
S>>>Кирилл, тебе же говорят — не надо так делать. Ты делаешь ненужную и вредную работу. Добрые дяди из борланд все сделали за тебя. S>>>В программе просто сделай uses на этот юнит и вызывай функцию ExecForm напрямую. В опциях проекта включи галку use runtime packages и не забудь указать имя своего пакета в списке. И будет тебе счастье с большой буквы с.
KB>>Да, так все работает, только приходится еще и dcp тащить вместе с bpl... KB>>А если загрузка динамичекая, как с экспортируемыми функциями работать?
ST>куда тащить ?
Когда указываешь build runtime packages, так указывается файл dcp а не bpl, соответственно при сборке оба эти файла должны быть в наличии а при запуске только bpl
Здравствуйте, Kirill Bezrukov, Вы писали:
KB>Здравствуйте, s.ts, Вы писали:
ST>>Здравствуйте, Kirill Bezrukov, Вы писали:
KB>>>Здравствуйте, Sinclair, Вы писали:
S>>>>Кирилл, тебе же говорят — не надо так делать. Ты делаешь ненужную и вредную работу. Добрые дяди из борланд все сделали за тебя. S>>>>В программе просто сделай uses на этот юнит и вызывай функцию ExecForm напрямую. В опциях проекта включи галку use runtime packages и не забудь указать имя своего пакета в списке. И будет тебе счастье с большой буквы с.
KB>>>Да, так все работает, только приходится еще и dcp тащить вместе с bpl... KB>>>А если загрузка динамичекая, как с экспортируемыми функциями работать?
ST>>куда тащить ?
KB>Когда указываешь build runtime packages, так указывается файл dcp а не bpl, соответственно при сборке оба эти файла должны быть в наличии а при запуске только bpl
это да, но в чем тут проблема ?
если очень хочется руками делать Loadpackage, пожалуйста...
не забудь толко, чтобы все пакеты, используемые приложением и твоим вручную загружаемым пакетом были перечислены в списке рантайм-пакетов
Здравствуйте, Kirill Bezrukov, Вы писали: KB>А если загрузка динамичекая, как с экспортируемыми функциями работать?
Ну, по идее так же. Только я не люблю с пакетами через exports работать. Поскольку как правило все-таки подключаются реализации не функций, а классов. Схему динамической привязки классов я уже приводил. Правило большого пальца — не использовать exports кроме случаев, когда ты вынужден это делать. exports суть пережиток темных времен процедурного программирования. Теперь у нас есть ООП и компонентная модель. Зачем этим феодализмом-то заниматься? Все прогрессивное человечество уже при посткапитализме живет
... << RSDN@Home 1.1.3 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Kirill Bezrukov, Вы писали: KB>>А если загрузка динамичекая, как с экспортируемыми функциями работать? S>Ну, по идее так же. Только я не люблю с пакетами через exports работать. Поскольку как правило все-таки подключаются реализации не функций, а классов. Схему динамической привязки классов я уже приводил. Правило большого пальца — не использовать exports кроме случаев, когда ты вынужден это делать. exports суть пережиток темных времен процедурного программирования. Теперь у нас есть ООП и компонентная модель. Зачем этим феодализмом-то заниматься? Все прогрессивное человечество уже при посткапитализме живет Это понятно... Но вот мне например надо, чтобы запускался блок расчета с визуальным редактированием параметров и передавать ей надо только базу данных и идентификатор объекта для которого считается...
Если сделать функцией, то получится:
function ExecCalculation(ADatabase: TIBDatabase; ObjectUNID: string): double;
Здравствуйте, s.ts, Вы писали:
ST>если очень хочется руками делать Loadpackage, пожалуйста... ST>не забудь толко, чтобы все пакеты, используемые приложением и твоим вручную загружаемым пакетом были перечислены в списке рантайм-пакетов
Можно поподробнее об этом... Т.е. если я в проекте пакета ставлю Build with run time packages, то и у программы его использующей надо делать тоже?
Здравствуйте, Kirill Bezrukov, Вы писали:
KB> Это понятно... Но вот мне например надо, чтобы запускался блок расчета с визуальным редактированием параметров и передавать ей надо только базу данных и идентификатор объекта для которого считается... KB> Если сделать функцией, то получится: KB>
KB> function ExecCalculation(ADatabase: TIBDatabase; ObjectUNID: string): double;
KB>
KB>А если делать классами, то:
Неа. Если классами — то получится примерно так:
unit CalculationBase;
interface
uses ...;
type
ICalculator = class
class function Exec(ADatabase: TIBDatabase; ObjectUNID: string): double; virtual; abstract;
end;
Теперь в коде
var
Res: double;
begin
res=ICalculateObject(GetClass('TConcreteCalculateObject')).Exec(ADatabase: TIBDatabase; ObjectUNID: string);
end;
Не надо недооценивать силу ООП
... << RSDN@Home 1.1.3 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Kirill Bezrukov, Вы писали: KB>Можно поподробнее об этом... Т.е. если я в проекте пакета ставлю Build with run time packages, то и у программы его использующей надо делать тоже?
Нет. Что ты ставишь в проекте пакета никакого значения не имеет. Просто когда ты делаешь у программы Build with run time packages, лучше позаботься о том, чтобы в ее списке были все пакеты, перечисленные в списке requires твоего пакета. Иначе при его динамической загрузке он их не найдет.
... << RSDN@Home 1.1.3 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Kirill Bezrukov, Вы писали:
S>
S> ICalculator = class
S> class function Exec(ADatabase: TIBDatabase; ObjectUNID: string): double; virtual; abstract;
S> end;
S>
S>Не надо недооценивать силу ООП
Вот это, мне кажется, совсем не ООП... Когда у класса только один метод класса и тот абстрактный... не очень красиво...
Здравствуйте, Kirill Bezrukov, Вы писали: KB>Вот это, мне кажется, совсем не ООП... Когда у класса только один метод класса и тот абстрактный... не очень красиво...
Ну, если очень хочется, то можно сделать и так:
type
ICalculator = class
class function Exec(CalcName: String; ADatabase: TIBDatabase; ObjectUNID: string): double;
constructor Create(ADatabase: TIBDatabase; ObjectUNID: string); virtual; abstract;
private
function Execute: double; virtual;abstract;
end;
implementation
class function ICalculator.Exec(CalcName: String; ADatabase: TIBDatabase; ObjectUNID: string): double;
begin
with GetClass(CalcName) as ICalculator do
begin
with Create(ADatabase: TIBDatabase; ObjectUNID: string) do
try
Result:= Execute;
finally
Free
end;
end;
end;
end.
... << RSDN@Home 1.1.3 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
или экспортировать интерфейсы — они (в качестве бонуса) еще и с COM совместимы.
а потом оформляешь как сервер, регистрируешь и получаешь другой, тоже стандартный подход