-
Привет Мастера! Встала проблемка: Есть главное приложение и пакет времени выполнения (BPL). В БПЛке есть переменная, нужно из главного приложения поменять ее значение. Можно и наоборот, БПЛка берет значение из переменной в главном приложении. Вопрос: Как реализовать?
-
Самый просто способ - экспортировать идентификатор переменной (см. exports)
-
Можно примерчик, а то инфы на эту тему ни вь хелпе ни в инете не нашел :(
-
program MyBPL; ... var MyExportedVariable: Integer; .. exports MyExportedVariable;
...
var pMyExportedVariable: PInteger;
hMyBPL := LoadLibrary('MyBPL.bpl'); pMyExportedVariable := GetProcAddress(hMyBPL, 'MyExportedVariable'); pMyExportedVariable^ := 1234;
-
Это мне расписал экспорт из DLL библиотеки. :) Дело в том что в package некуда впихнуть Exports :( Вот код: package r3DWorkers;
requires
rtl,
vcl,
dbrtl,
vcldb,
te_d6,
te_db_d6,
ibxpress;
contains
uDWorkersWF in 'uDWorkersWF.pas' ;
end. В главном приложении var
HM_R3DWorkers: HModule;
DWorkersWFrm: TForm;
FrmClass: TFormClass;
procedure TMainForm.MPMDWorkersClick(Sender: TObject);
begin
HM_R3DWorkers:=LoadPackage('libs\r3dworkers.bpl');
if HM_R3DWorkers>0 then begin
FrmClass:=TFormClass(GetClass('TDWorkersWF'));
if Assigned(FrmClass) then begin
DWorkersWFrm:=FrmClass.Create(self);
DWorkersWFrm.Show;
end;
end;
end;
-
Вобщем опять сделал выводы :) Использовать лучше DLL чем BPL, но при этом и в DLL и в главном приложении использовать build with run-time packages
-
> в package некуда впихнуть Exports
А справка говорит иначе:
An exports clause can appear anywhere and any number of times in the declaration part of a program or library, or in the interface or implementation section of a unit.
-
> Sirus (18.02.08 12:50) > В БПЛке есть переменная, нужно из главного приложения поменять ее > значение.
unit OneOfBplUnits;
interface
var
MyMagicVar: MyMagicType;
...
end.
=======================
unit OneOfExeUnits;
uses
OneOfBplUnits;
...
implementation
procedure MyMagicClass.MyMagicProc;
begin
MyMagicVar := MyMagicValue; end;
-
> Семеныч (19.02.08 09:45) [7]
Работать это не будет.
-
> Сергей М. © (19.02.08 09:06) [6] Речь идет не о Library, а о Package (при компиляции создается файл *.bpl а не *.dll)
> Семеныч (19.02.08 09:45) [7] То есть если есть один общий модуль Unit1.pas, то изменение значения переменной в этом модуле из главного приложения приведет к изменению значения этой переменной в BPL?
-
Сергей М. © (19.02.08 09:57) [8]
А куда оно денется - при статической линковке будет работать на ура.
-
> Сергей М. © (19.02.08 09:57) [8] > > > Семеныч (19.02.08 09:45) [7] > > > Работать это не будет.
Действительно не работает :(
-
> Sirus (19.02.08 09:59) [9]
Пакет - это, по сути, та же библиотека, только вид сбоку) Пакет (bpl) и библиотека (dll) есть, прежде всего, PE-модуль, который подразумевает таблицу экспорта.
Читай внимательно - exports clause can appear anywhere and any number of times in the declaration part of a program or library, or in the interface or implementation section of a unit
-
> Сергей М. © (19.02.08 09:57) [8]
А куда оно денется - при статической линковке будет работать на ура. (c) Игорь Шевченко
> Sirus (19.02.08 09:59) [9]
> если есть один общий модуль Unit1.pas, то изменение значения > переменной в этом модуле из главного приложения приведет к > изменению значения этой переменной в BPL?
При статической линковке по барабану, где эта переменная расположена. Лишь бы она была доступна.
> Sirus (19.02.08 10:05) [11]
Значит, Вы используете динамическую линковку. Но нигде об этом не сказали - а как раз об этом и надо было сказать в первую очередь.
-
> Sirus (19.02.08 05:40) [4] > ... > В главном приложении > var > HM_R3DWorkers: HModule; > DWorkersWFrm: TForm; > FrmClass: TFormClass; > > procedure TMainForm.MPMDWorkersClick(Sender: TObject); > begin > HM_R3DWorkers:=LoadPackage('libs\r3dworkers.bpl'); > if HM_R3DWorkers>0 then begin > FrmClass:=TFormClass(GetClass('TDWorkersWF')); > if Assigned(FrmClass) then begin > DWorkersWFrm:=FrmClass.Create(self); > DWorkersWFrm.Show; > end; > end; > end;
Здесь указал... т.е. не сказал что динамически, но из кода видно и так. Теперь когда выяснили что имеем дело с динамической подгрузкой BPL, какие будут советы?
-
Проблемку решил немножко другим путем, создал наследник от TForm в котором создал необходимые мне свойства.
Теперь возникает другой вопрос: Как правильно выгрузить пакет BPL с немодальной формой внутри?
-
> Здесь указал... т.е. не сказал что динамически, но из кода > видно и так.
Дорогой друг, у нас проблемы с переменными, пакетами и прочей фигней нету и нам ее решать не надо. Проблема есть у тебя и в твоих интересах не притворятся партизаном, попавшим в плен к злым гестаповцам и ни за что не желающим открыть врагу военную тайну.
> Теперь возникает другой вопрос: Как правильно выгрузить > пакет BPL с немодальной формой внутри?
Да пофиг как выгружать. Если у тебя при выгрузке какие-то проблемы, то нехреново бы их здесь озвучить, если проблем нету, то очевидно и спрашивать незачем, выгружай, как хочется и не мучайся.
-
Приношу свои извинения за "видно итак" :) Загружаю пакет procedure TMainForm.MPMDWorkersClick(Sender: TObject);
begin
HM_R3DWorkers:=LoadPackage('libs\r3dworkers.bpl');
if HM_R3DWorkers>0 then begin
SFClass:=TSrsFormClass(GetClass('TDWorkersWF'));
if Assigned(SFClass) then begin
DWorkersWFrm:=SFClass.Create(self);
DWorkersWFrm.MainDir:=MainDir;
DWorkersWFrm.MainFormHandle:=MainForm.Handle;
DWorkersWFrm.Show;
end;
end;
end; Форма из пакета грузится, все тип-топ... При закрытии формы в OnClose PostMessage(MainFormHandle, WM_USER+301, 0, 0); В главном приложении обрабатываю сообщение Procedure TMainForm.WMFCDWorkers(var Msg: TMessage);
Begin
UnloadPackage(HM_R3DWorkers);
End; При обработке сообщения возникает Access violation... Паралелльно есть ееще вопрос: Нужно чтобы при клике в меню форма создавалась только если ее нет, а если есть то просто отображалась (выходила на передний план).
-
Если сделать так Procedure TMainForm.WMFCDWorkers(var Msg: TMessage);
Begin
UnloadPackage(HM_R3DWorkers);
End То ошибка пропадает, но возникает вопрос: Правильно ли это?
-
Если сделать так Procedure TMainForm.WMFCDWorkers(var Msg: TMessage);
Begin
DWorkersWFrm.Free;
UnloadPackage(HM_R3DWorkers);
End То ошибка пропадает, но возникает вопрос: Правильно ли это?
-
По моему все :) Тему можно считать закрытой
|