![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Доступ к компоненту из DLL
Olegas © (2006-06-08 09:19:00)У меня есть приложение и в нем компоненты работающие с базой данных Interbase. Это прежде всего TTable и TQuery.
Мне нужно написать DLL, Функции из которой вызывались бы из приложения и чтобы изнутри таких функций можно было обращаться к компонентам TTable и TQuery созданным в основном приложении. Как получить к ним доступ из DLL?
Как это сделать?
kaif (2006-06-15 16:47:00) [1]У меня есть еще один вопрос. Надеюсь, он не будет выглядеть как оффтопик.
Допустим я хочу построить систему так:
1. Сделать на сервере папку MY_PROGRAM\BIN и расшарить ее на чтение.
2. Сунуть туда my_program.exe + *.bpl, которые входят в мою систему.
3. Сунуть туда клиента Firebird (gds32.dll) для того чтобы настройка компьютера пользователя сводилась только к настройке ярлыка к my_program.exe.
----------------------------
Так вот такой вопрос.
Могу ли я все системные BPL-ы (vcl60.bpl,rtl60.bpl и им подобные) тоже сунуть в эту директорию \BIN на сервере или я обязан их устанавливать в Windows\System каждого клиентского компьютера и регистрировать эти bpl-ы?
Мне почему-то кажется, что могу все сунуть в директорию программы \BIN на сервере.
Или я неправ?
kaif (2006-06-15 15:52:00) [2]ANB © (15.06.06 14:57) [30]
Отчеты с помощью чего выводим ?
Я попробовал с помощью FastReport - работает из BPL без проблем. Даже в MDI - режиме.
zorik (2006-06-15 15:48:00) [3]http://delphimaster.ru/cgi-bin/forum.pl?id=1149574520&n=1
ANB (2006-06-15 14:57:00) [4]Отчеты с помощью чего выводим ?
kaif (2006-06-15 13:38:00) [5]Вообще Ваш способ (Form1.db.Handle := DBHandle;) мне больше нравится. Я чувствую, что наличие компонента db на форме может помочь при дизайне и отладке модуля.
kaif (2006-06-15 13:10:00) [6]2 Панас (15.06.06 11:10) [27]
У меня практически то же самое.
Кроме способа передачи данных о базе.
Я передаю непосредственно указатель типа TIBDatabase. В пакетах (BPL) это возможно.
===============================
Правда после двух дней экспериментов меня стали мучать сомнения насчет того, что это оптимальный способ написать систему, работающую с базой данных.
Дело в том что при развитии системы если она состоит из версии EXE и версии базы, то их можно сравнивать и либо апгредить базу до EXE - для этого я обычно поставляю новую dbupdate.dll вместе с новым EXE (внутри этой dbupdate.dll лежит кумулятивный код всех апдейтов базы), либо просить скачать новый EXE + dbupdate.dll, если база имеет более позднюю версию. В случае же множества модулей задача апдейтов начинает не упрощаться, а усложняться.
Так что я склоняюсь к мысли о том, чтобы в EXE запихнуть все модули, кроме отчетов. Так как основные модули (ввод данных и т.п.) изменяются редко и как правило в связи с изменением структуры базы.
А вот отчеты как раз лучше видимо добавлять через механизм BPL.
Отчеты неправильных версий, хотя и чувствительны к структуре базы, но не так фатально опасны для нее, так как работают в режиме "только чтение".
Так что пока что я в раздумьях. Жаль выкидывать столько работы. Хотя для отчетов этот механизм, я думаю, окажется оптимальным. К тому же BPL для отчетов хороши тем, что можно добавлять новые отчеты, не останавливая работу пользователей.
Панас (2006-06-15 11:10:00) [7]
unit1;
//форма в DLL, на ней лежит TpFIBDatabase
procedure ShowFormFromDLL(AppHandle: THandle; DBHandle: TISC_DB_HANDLE); StdCall;
exports
ShowFormFromDLL;
implementation
procedure ShowFormFromDLL(AppHandle: THandle; DBHandle: TISC_DB_HANDLE);
begin
try
Application.Handle := AppHandle;
Form1 := TForm1.Create(Application);
Form1.db.Handle := DBHandle;
Form1.dt.Open;
Form1.ShowModal;
finally
Form1.dt.Close;
Application.Handle := 0;
Form1.Free;
end;
end;
/////////////////////////////////////
//вызывающий модуль
type
TShowFormFromDLL = procedure (AppHandle: THandle; DBHandle: TISC_DB_HANDLE); stdcall;
TDisconnectInDLL = procedure; stdcall;
EDLLLoadError = class(Exception);
// на кнопку грузим DLL и вызываем ее метод для отображения формы
procedure TForm1.Button1Click(Sender: TObject);
var
DLLHandle: THandle;
ShowFormFromDLL: TShowFormFromDLL;
ExePath: string;
begin
ExePath := ExtractFilePath(Application.ExeName);
DLLHandle := LoadLibrary(PChar(ExePath + 'testdll.dll'));
try
if DLLHandle <= 0 then
MessageDlg('Error loading ' + QuotedStr(ExePath + 'testdll.dll'),
mtError, [mbOk], 0);
@ShowFormFromDLL := GetProcAddress(DLLHandle, 'ShowFormFromDLL');
if Assigned(ShowFormFromDLL)
then ShowFormFromDLL(Application.Handle, db.Handle)
else MessageDlg('Error execute ShowFormFromDLL', mtError, [mbOk], 0);
finally
Application.ProcessMessages;
FreeLibrary(DLLHandle);
end;
end;
kaif (2006-06-14 15:22:00) [8]Я лично просто объявил в секции export модуля:
unit UsersMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IBDatabase;
type
TUsersMainForm = class(TForm)
IBTransaction1: TIBTransaction;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
....
private
{ Private declarations }
public
{ Public declarations }
end;
var
UsersMainForm: TUsersMainForm;
implementation
{$R *.dfm}
{$R UsersImages.res}
function CreateModuleMainForm(ADatabase: TIBDatabase): TForm;
begin
Result := TUsersMainForm.Create(nil);
TUsersMainForm(Result).IBTransaction1.DefaultDatabase := ADatabase;
end;
procedure TUsersMainForm.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
Action := caFree;
end;
exports
CreateModuleMainForm;
end.
Все работает.
Проверил с помощью tdump.
Экспорт как экспорт.
Не знаю, наверно это тоже безграмотно.
Я уже ни в чем не уверен.
С пакетами я раньше дела не имел.
Если есть кто грамотный на этот счет - отзовитесь.
Olegas (2006-06-14 13:57:00) [9]как из него экспортировать процедуры и функции?
Сергей М. (2006-06-14 13:35:00) [10]
> Olegas (14.06.06 12:04) [23]
смю. File -> New -> Other.. -> Package
Olegas (2006-06-14 12:04:00) [11]Так что, никто не подскажет пример, как вместо dll построить bpl?
Сергей М. (2006-06-14 08:46:00) [12]
> Olegas (13.06.06 16:56) [19]
>
> Насчет sharemem поподробнее можно?
Юнит ShareMem может быть использован в случаях, когда модули, разработанные в борладовских средах (Делфи и BСС), должны обмениваться данными дин.типов (память под которые распределяется динамически в ходе работы приложения, явно или неявно) при условии невозможности по тем или иным причинам сборки этих взаимодействующих модулей с использованием пакетов времени выполнения.
ShareMem является интерфейсом для используемой в этом случае библиотеки borlandmm.dll, в которой реализован единый для взаимодействующих модулей менеджер памяти.
ShareMem должен быть указан первымюнитам в секции uses проектоввзаимодействующих модулей.
Olegas (2006-06-14 08:38:00) [13]>kaif
Еще маленький вопрос. Как сделать вместо dll bpl?
До сих пор я сталкивался с bpl при компиляции библиотеки компонентов. Создавался проект dpk и в него помещались исходники форм и модулей.
Как экспортировать процедуры и функции в этом случае?
Если можно, небольшой пример.
kaif (2006-06-13 17:07:00) [14]Андрей Пазик (13.06.06 16:52) [18]
kaif, зочем ви так пишете? Да еще и учите неграмотные умы? В dll/bpl нужно передавать Handle объекта Database, а не сам Database (не важно, IBDatabase или FIBDatabase или еще что). После чего нужно в dll/bpl создать объект IBDatabase, и присвоить ему переданный Handle.
Кому нужно?
И почему нужно?
Я пишу то, что можно сделать без проблем, это совершенно грамотно, и это будет работать без проблем.
А вообще. конечно, можно вообще без компонентов обойтись.
И без *.bpl всяких.
Передавать только указатели, пчары, аллокировать память под строки, общаться исключительно по соглашению stdcall.
Грузить динамически руками gds32.dll и юзать ее функции и это будет еще ГРАМОТНЕЕ.
Одни сплошные хендлы и PChar-ы.
У меня нет цели "учить безграмотные умы".
Моя цель в данном случае - помочь человеку быстро решить его насущные проблемы. Дельфи для этого и был разработан. Для решения ЗАДАЧ.
Если Вы уверены, что указатель типа TIBDatabase нельзя передавать в качестве параметра при вызове функции из bpl, покажите мне запрет на такой вызов в ДОКУМЕНТАЦИИ ДЕЛЬФИ.
:(
Olegas (2006-06-13 16:56:00) [15]Насчет sharemem поподробнее можно?
Андрей Пазик (2006-06-13 16:52:00) [16]kaif, зочем ви так пишете? Да еще и учите неграмотные умы? В dll/bpl нужно передавать Handle объекта Database, а не сам Database (не важно, IBDatabase или FIBDatabase или еще что). После чего нужно в dll/bpl создать объект IBDatabase, и присвоить ему переданный Handle.
Сергей М. (2006-06-13 16:35:00) [17]
> Olegas (13.06.06 14:15) [13]
> что это собственно меняет?
Это гарантирует использование обоими модулями единого экз-ра менеджера памяти. Гарантирует, естественно. при условии, что ты не намудрил с ShareMem.
kaif (2006-06-13 16:27:00) [18]Olegas (13.06.06 15:52) [15]
>kaif
А в функцию из bpl можно таким же образом передать доступ именно к TTable или TQuery?
А почему бы нет?
Olegas (2006-06-13 15:52:00) [19]>kaif
А в функцию из bpl можно таким же образом передать доступ именно к TTable или TQuery?
Olegas (2006-06-13 15:16:00) [20]>API
А примерчик можно?