Форум: "Базы";
Текущий архив: 2005.10.09;
Скачать: [xml.tar.bz2];
ВнизКак передать коннект к базе Firebird из программы в dll? Найти похожие ветки
← →
Akris © (2005-08-27 20:11) [0]Подскажите, пожалуйста, как передать коннект к базе данных Firebird из основной программы в dll так, чтобы было только одно соединение с базой.
Пробовал передавать компонент TpFIBDataBase - вылетает Access Violation по адресу в библиотеке.
Я использую компоненты FibPlus 4.8.
← →
Sergey Masloff (2005-08-27 20:54) [1]Не надо это делать. Просто на такие грабли наступишь...
← →
Akris © (2005-08-27 21:09) [2]Тогда как решить следующую задачу:
есть основное приложение, которое реализует подключение к базе данных и есть три справочника - которые реализуются dll. Если не передавать коннект, тогда при открытии всех трех справочников будем иметь четыре соединения с базой данных: одно соединение из основного приложения и по одному из каждого справочника. А это не есть гуд!!!
Кстати, какие есть грабли?
← →
Sergey Masloff (2005-08-27 22:00) [3]Использовать пакеты (package) а не dll, но работоспособностья лично не проверял. На фига справочники в dll? Тоже непонятно
← →
}{ander © (2005-08-27 22:01) [4]> будем иметь четыре соединения с базой данных
Ну и что? Хоть 10 соединений - для FB это, имхо, не проблема.
← →
Akris © (2005-08-28 12:39) [5]> На фига справочники в dll?
Потому что нужно сделать возможность вида и содержимого справочника. А поскольку справочник в dll тода можно менять только одну отдельную dll вместо замены всего приложения.
> Ну и что? Хоть 10 соединений - для FB это, имхо, не проблема.
Согласен что не проблема, но для SuperServer. Да и к тому же на каждое соединение с базой будет уходить время, а при использовании уже открытого соединения нет этих затрат.
← →
sniknik © (2005-08-28 13:01) [6]> Согласен что не проблема, но для SuperServer.
для любого сервера десяток соеденений не проблема. имхо. если только лицензия не на 5-ть ;о)).
проблема будет если использовать персонал(ембедед) версию... гдe возможно всего одно подключение.
но в общем не понятно в чем проблема, не скажу за TpFIBDataBase но ADOconnection и Database(BDE) в dll передавал (просто тесты. в реальных программах такой нужды не возникало) все отлично передается... не думаю что FIB-ы глючат, скорее твоя реализация их использования "с брачком".
1-е проверь соглашения о вызовах, чтобы совпадали в dll и exe.
2-e внимательно прочитай коментарий при создании dll создающийся, там явное указание насчет менеджера памяти, и что делать, чтобы передавались строки и обьекты.
впечатление что ты это сообщение проигнорировал.
3-е описывай проблему подробно, с примерами и кодом. пока по твоему описанию ничего не понять.
← →
DrPass © (2005-08-28 13:13) [7]Скорее всего, проблема в отсутствии пресловутого ShareMem. Я в свое время делал такой финт с DLL (только не с FIBPlus, а с IBExpress). В принципе, жалоб и подводных камней не было (была, правда, проблема с обработкой событий - но это уже "особенности" архитектуры IBExpress)
← →
Desdechado © (2005-08-29 12:05) [8]а млжет, при вызове DLL ты в ней не указываешь вызвавшее приложение в качестве Application?
или с разными версиями компонентов компилируешься - тогда 100% глюки будут
← →
Domkrat © (2005-08-29 12:24) [9]У нас реализован вариант: exe (1 конект) + BPL.
Экзешка реализует интерфейс, который возвращает конекшн, который можно вызвать из BPL.
← →
Akris © (2005-08-29 15:36) [10]Код приложения, который вызывает форму из DLL:
type
//Объявление процедурного типа для вызова формы из DLL
TShowForm = procedure (DataBase: Pointer); stdcall;
{...}
//Вызов формы из DLL
procedure TfrMain.Button1Click(Sender: TObject);
var
LibHandle: THandle;
LibFunction: TShowForm;
begin
{Делаем попытку загрузить Dll}
LibHandle := LoadLibrary(PChar(ExtractFileDir(ParamStr(0))+"\PenniesDll\PenniesLib.dll"));
try
{Если загрузка Dll окажется неудачной, переменная LibHandle будет иметь
нулевое значение. В этом случае возникнет исключительная ситуация}
if (LibHandle = 0) then
begin
raise EDLLLoadError.Create("Не могу загрузить Dll");
end;
{Устанавливаем связь с экспортируемой функцией}
@LibFunction := GetProcAddress(LibHandle, "ShowForm");
{Если функция экспортируется удачно, тогда возвращаем результат}
if not(@LibFunction = nil) then
LibFunction(Pointer(DM.DataBase))
else
RaiseLastWin32Error;
except
//Выгружаем библиотеку
FreeLibrary(LibHandle);
end;
end;
Код в DLL, который создает форму. На форме DBGrid, DataSource, FIBDataSet, FIBTransaction.
//------------------------------------------------------------------------------
procedure ShowForm(aDataBase: Pointer); stdcall;
begin
Form1 := TForm1.Create(Application);
Form1.Show;
//Здесь вылетает Access Violetion in module PenniesLib
DM.DataBase := TpFIBDatabase(aDataBase);
DM.dstTemp.Database := DM.DataBase;
DM.dstTemp.SelectSQL.Add("SELECT * FROM USERS");
DM.dstTemp.Open;
Form1.ds.DataSet := DM.dstTemp;
Form1.DBGrid1.Align := alClient;
end;
← →
Akris © (2005-08-29 15:37) [11]Код приложения, который вызывает форму из DLL:
type
//Объявление процедурного типа для вызова формы из DLL
TShowForm = procedure (DataBase: Pointer); stdcall;
{...}
//Вызов формы из DLL
procedure TfrMain.Button1Click(Sender: TObject);
var
LibHandle: THandle;
LibFunction: TShowForm;
begin
{Делаем попытку загрузить Dll}
LibHandle := LoadLibrary(PChar(ExtractFileDir(ParamStr(0))+"\PenniesDll\PenniesLib.dll"));
try
{Если загрузка Dll окажется неудачной, переменная LibHandle будет иметь
нулевое значение. В этом случае возникнет исключительная ситуация}
if (LibHandle = 0) then
begin
raise EDLLLoadError.Create("Не могу загрузить Dll");
end;
{Устанавливаем связь с экспортируемой функцией}
@LibFunction := GetProcAddress(LibHandle, "ShowForm");
{Если функция экспортируется удачно, тогда возвращаем результат}
if not(@LibFunction = nil) then
LibFunction(Pointer(DM.DataBase))
else
RaiseLastWin32Error;
except
//Выгружаем библиотеку
FreeLibrary(LibHandle);
end;
end;
Код в DLL, который создает форму. На форме DBGrid, DataSource, FIBDataSet, FIBTransaction.
//------------------------------------------------------------------------------
procedure ShowForm(aDataBase: Pointer); stdcall;
begin
Form1 := TForm1.Create(Application);
Form1.Show;
//Здесь вылетает Access Violetion in module PenniesLib
DM.DataBase := TpFIBDatabase(aDataBase);
DM.dstTemp.Database := DM.DataBase;
DM.dstTemp.SelectSQL.Add("SELECT * FROM USERS");
DM.dstTemp.Open;
Form1.ds.DataSet := DM.dstTemp;
Form1.DBGrid1.Align := alClient;
end;
← →
Desdechado © (2005-08-29 16:30) [12]1. DM.DataBase в вызывающем модуле - неизвестно что
2. я бы передал в DLL еще и Application.Handle, а в DLL присвоил бы его ейному Application.Handle (а перед завершением DLL-функции и восстановил бы)
3. Form1 в DLL похоже на глобальную переменную. Есть неплохой шанс использовать ее ненароком несколько раз, нахватавшись глюков
4. выгрузку библиотеки я поставил бы не на except, а на finally, а так у тебя она остается болтаться в случае неошибки, что приведет к ошибке при следующем ее вызове
5. я бы еще для ShowForm возвращал статус или Handle формы, чтоб ее потом закрыть корректно можно было
← →
Akris © (2005-08-29 16:49) [13]1. DM.DataBase в вызывающем модуле - это компонент TpFIBDataBase в DataModule.
3. Form1 в DLL глобальная переменная - я понял и убрал.
4. Выгрузка библиотеки стоит на except - такова логика программы.
5. Закрываю форму я другой процедурой, которая вызывается из dll.
Спасибо всем, кто ответил. Рабочий код следующий:
type
//Объявление процедурного типа для вызова формы из DLL
TShowForm = procedure (AppHandle: THandle;BaseHandle: TISC_DB_HANDLE); stdcall;
{...}
//Вызов формы из DLL
procedure TfrMain.Button1Click(Sender: TObject);
var
LibHandle: THandle;
LibFunction: TShowForm;
begin
{Делаем попытку загрузить Dll}
LibHandle := LoadLibrary(PChar(ExtractFileDir(ParamStr(0))+"\PenniesDll\PenniesLib.dll"));
try
{Если загрузка Dll окажется неудачной, переменная LibHandle будет иметь
нулевое значение. В этом случае возникнет исключительная ситуация}
if (LibHandle = 0) then
begin
raise EDLLLoadError.Create("Не могу загрузить Dll");
end;
{Устанавливаем связь с экспортируемой функцией}
@LibFunction := GetProcAddress(LibHandle, "ShowForm");
{Если функция экспортируется удачно, тогда возвращаем результат}
if not(@LibFunction = nil) then
LibFunction(Application.Handle, DM.DataBase.Handle)
else
RaiseLastWin32Error;
except
//Выгружаем библиотеку
FreeLibrary(LibHandle);
end;
end;
Код в DLL, который создает форму. На форме DBGrid, DataSource, FIBDataSet, FIBTransaction.
//------------------------------------------------------------------------------
procedure ShowForm(AppHandle: THandle;BaseHandle: TISC_DB_HANDLE); stdcall;
begin
Application.Handle := AppHandle;
DM := TDM.Create(Application);
Form1 := TForm1.Create(Application);
Form1.Show;
DM.DataBase.Handle := BaseHandle;
DM.dstTemp.Database := DM.DataBase;
DM.dstTemp.SelectSQL.Add("SELECT * FROM USERS");
DM.dstTemp.Open;
Form1.ds.DataSet := DM.dstTemp;
Form1.DBGrid1.Align := alClient;
end;
Причина вылета: не было создания DataModule.
Спасибо Peter за помощь.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2005.10.09;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.012 c