Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Доступ к компоненту из DLL


Страницы:   1 2

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
А примерчик можно?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо