![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Доступ к компоненту из DLL
Olegas © (2006-06-08 09:19:00)У меня есть приложение и в нем компоненты работающие с базой данных Interbase. Это прежде всего TTable и TQuery.
Мне нужно написать DLL, Функции из которой вызывались бы из приложения и чтобы изнутри таких функций можно было обращаться к компонентам TTable и TQuery созданным в основном приложении. Как получить к ним доступ из DLL?
Как это сделать?
Olegas (2006-06-13 14:15:00) [21]>Сергей М.
А что это собственно меняет? Ну собрал, с тем же результатом. Никакого счастья.
kaif (2006-06-13 13:21:00) [22]Пардон, описался.
Употребил два разных названия
TCreateModuleMainWindow и TCreateModuleMainForm.
На самом деле в проекте используется название TCreateModuleMainForm.
kaif (2006-06-13 13:19:00) [23]Я сейчас пишу что-то подобное.
Правда у меня не TTable и TQuery, а IBDatabase + одна IBTransaction (read)
в основной программе.
Использую опцию проекта Build with runtime packages.
То есть *.bpl.
В формах (они у меня MDIChild, каждый плагин имеет одну такую "основную форму") использую IBDataSet или IBQuery + IBTransaction.
Модуль экспортирует функцию:
function CreateModuleMainWindow(ADatabase: TIBDatabase): TForm.
В основном приложении имею процедурный тип:
type
TCreateModuleMainWindow = function(ADatabase: TIBDatabase): TForm;
Загружаю *.bpl рантайм функцией LoadPackage.
Нахожу точку входа через GetProcAddress, приводя указатель на функцию к типу TCreateModuleMainWindow:
var
MyModule: HMODULE = 0;
CreateModuleMainForm: TCreateModuleMainForm;
...
begin
if MyModule = 0 then
begin
MyModule := LoadPackage('MyPackage.bpl');
CreateModuleMainForm := GetProcAddress(MyModule, 'CreateModuleMainForm');
end;
//Вызываю функцию.
Form := CreateModuleMainForm(MainConnection.MainDatabase);
Form.Name := 'MyPackage';
Form.Caption := GetPackageDescription('MyPackage.bpl');
end;
У меня возникает дочернее окно. Компоненты на этом окне получают доступ к базе данных через параметр ADatabase, который я передаю при вызове функции (это присвоение осуществляется внутри пакета).
Все прекрасно работает.
Пакет потом можно выгрузить вызовом UnloadPackage.
Перекомпиляции основного приложения не требуется. Модули можно добавлять. Важно лишь чтобы приложение имело механизм узнать, какие модули еще добалены в систему, чтобы создать нужные пункты меню при старте. Я намерен эту информацию сохранять в реестре.
Сергей М. (2006-06-13 12:25:00) [24]
> Olegas (13.06.06 12:13) [9]
Собери оба проекта (проект хост-приложения и проект DLL) с опцией Build With Run-Time Packages и будь счастлив
Olegas (2006-06-13 12:13:00) [25]Я пробовал передать в процедуру, находящуюся в dll, в качестве параметра указатель на объект TTable. А в самой этой процедуре открываю форму и на ней определяю компонент Datasource, при этом свойству Datasource.dataset присваиваю полученный в качестве параметра Ttable. Дальше на форме есть Grid, Ему в качестве datasource присваиваю созданный компонент datasource. В результате выполнения получил runtime error.
Получается, так делать нельзя. Почему?
API (2006-06-11 22:12:00) [26]1. Вызвать из Dll процедуру, которая выдает на экран форму для заполнения.
2. Пользователь ее заполняет, а по кнопке ОК
3. обновляются данные в датасетах (добавляются, удаляются, модифицируются записи). При этом датасеты есть объекты созданные в основной программе
4. После чего соответствующую процедуру можно выгрузить из памяти.
1. Создать ClientDataSet := TClientDataset.Create();
2. Скопировать в ClientDataSet структуру таблицы из DataSet'а в основной программе.
3. При необходимости - скопировать запись (несколько записей) из DataSet'а в ClientDataSet.
4. Передать в DLL интерфейсную ссылку на ClientDataSet.DSBase (IDSBase)
5. Прилинковать переданную интерфейсную ссылку к внутреннему (DLL) TClientDataSet'у.
6. Далее - необходимые действия; TClientDataSet - потомок TDataSet.
7. Вернуть в основную программу интерфейсную ссылку на DSBase.
8. В основной программе - прилинковать ссылку к ClientDataSet, и "перекачать" данные в DataSet основной программы.
9. Повторить... :-)
P.S. Или BPL.
P.S. А если без BPL, то без интерфейсов - никак. Иначе - [5].
vvh (2006-06-11 19:49:00) [27]Подобная работа с DLL подробно расматривается в книге Ковязина - "Дельфи6/7, базы данных и приложения". У меня самого приложения построено именно так. Скажи что именно, у тебя не получается?
дид Панас (2006-06-10 11:40:00) [28]определяй интерфейс, передавай в BPL (а не dll) хендлы базы данных и application, по интерфейсу получай что тебе нужно.
ANB (2006-06-09 14:07:00) [29]
> Olegas (09.06.06 14:02) [4]
Тогда готовься собирать AV в самых неожиданных местах.
Olegas (2006-06-09 14:02:00) [30]Это исключено
ANB (2006-06-09 12:51:00) [31]Создавать эти наборы данных в самой DLL.
Olegas (2006-06-09 08:30:00) [32]Моя dll это что-то вроде плаггина.
Есть основная программа. И мне надо заложить на будущее средство для расширения ее возможностей за счет вызова внешних модулей.
В основной программе есть датасеты. Мне надо:
1. Вызвать из Dll процедуру, которая выдает на экран форму для заполнения.
2. Пользователь ее заполняет, а по кнопке ОК
3. обновляются данные в датасетах (добавляются, удаляются, модифицируются записи). При этом датасеты есть объекты созданные в основной программе
4. После чего соответствующую процедуру можно выгрузить из памяти.
И как это сделать?
DSKalugin (2006-06-08 12:10:00) [33]бред, изложи суть более внятно
П.С. С Interbase уже лет эдак 7 никто не работает через BDE