Конференция "Основная" » Переменные пакетов времени выполнения [D6, Win2k, WinXP]
 
  • Sirus (18.02.08 12:50) [0]
    Привет Мастера!
    Встала проблемка: Есть главное приложение и пакет времени выполнения (BPL). В БПЛке есть переменная, нужно из главного приложения поменять ее значение. Можно и наоборот, БПЛка берет значение из переменной в главном приложении.
    Вопрос: Как реализовать?
  • Сергей М. © (18.02.08 13:21) [1]
    Самый просто способ - экспортировать идентификатор переменной (см. exports)
  • Sirus (18.02.08 14:04) [2]
    Можно примерчик, а то инфы на эту тему ни вь хелпе ни в инете не нашел :(
  • Сергей М. © (18.02.08 14:34) [3]
    program MyBPL;
    ...
    var
     MyExportedVariable: Integer;
    ..
    exports MyExportedVariable;

    ...

    var
     pMyExportedVariable: PInteger;

    hMyBPL := LoadLibrary('MyBPL.bpl');
    pMyExportedVariable := GetProcAddress(hMyBPL, 'MyExportedVariable');
    pMyExportedVariable^ := 1234;
  • Sirus (19.02.08 05:40) [4]
    Это мне расписал экспорт из DLL библиотеки. :)
    Дело в том что в package некуда впихнуть Exports :(

    Вот код:
    package r3DWorkers;

    {$R *.res}
    {$ALIGN 8}
    {$ASSERTIONS ON}
    {$BOOLEVAL OFF}
    {$DEBUGINFO ON}
    {$EXTENDEDSYNTAX ON}
    {$IMPORTEDDATA ON}
    {$IOCHECKS ON}
    {$LOCALSYMBOLS ON}
    {$LONGSTRINGS ON}
    {$OPENSTRINGS ON}
    {$OPTIMIZATION ON}
    {$OVERFLOWCHECKS OFF}
    {$RANGECHECKS OFF}
    {$REFERENCEINFO ON}
    {$SAFEDIVIDE OFF}
    {$STACKFRAMES OFF}
    {$TYPEDADDRESS OFF}
    {$VARSTRINGCHECKS ON}
    {$WRITEABLECONST OFF}
    {$MINENUMSIZE 1}
    {$IMAGEBASE $400000}
    {$IMPLICITBUILD ON}

    requires
     rtl,
     vcl,
     dbrtl,
     vcldb,
     te_d6,
     te_db_d6,
     ibxpress;

    contains
     uDWorkersWF in 'uDWorkersWF.pas' {DWorkersWF};

    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;

  • Sirus (19.02.08 07:58) [5]
    Вобщем опять сделал выводы :)
    Использовать лучше DLL чем BPL, но при этом и в DLL и в главном приложении использовать build with run-time packages
  • Сергей М. © (19.02.08 09:06) [6]

    > в 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.
  • Семеныч (19.02.08 09:45) [7]
    > Sirus   (18.02.08 12:50)  

    > В БПЛке есть переменная, нужно из главного приложения поменять ее
    > значение.

    unit OneOfBplUnits;

    interface

    var
     MyMagicVar: MyMagicType;
    ...
    end.

    =======================

    unit OneOfExeUnits;

    uses
     OneOfBplUnits;

    ...

    implementation

    procedure MyMagicClass.MyMagicProc;
    begin
     MyMagicVar := MyMagicValue; // MyMagic code!!!
    end;

  • Сергей М. © (19.02.08 09:57) [8]

    > Семеныч   (19.02.08 09:45) [7]


    Работать это не будет.
  • Sirus (19.02.08 09:59) [9]
    > Сергей М. ©   (19.02.08 09:06) [6]
    Речь идет не о Library, а о Package (при компиляции создается файл *.bpl а не *.dll)

    > Семеныч   (19.02.08 09:45) [7]
    То есть если есть один общий модуль Unit1.pas, то изменение значения переменной в этом модуле из главного приложения приведет к изменению значения этой переменной в BPL?
  • Игорь Шевченко © (19.02.08 10:01) [10]
    Сергей М. ©   (19.02.08 09:57) [8]

    А куда оно денется - при статической линковке будет работать на ура.
  • Sirus (19.02.08 10:05) [11]

    > Сергей М. ©   (19.02.08 09:57) [8]
    >
    > > Семеныч   (19.02.08 09:45) [7]
    >
    >
    > Работать это не будет.

    Действительно не работает :(
  • Сергей М. © (19.02.08 10:19) [12]

    > 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 11:13) [13]
    > Сергей М. ©   (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 11:21) [14]

    > 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, какие будут советы?
  • Sirus (19.02.08 12:13) [15]
    Проблемку решил немножко другим путем, создал наследник от TForm в котором создал необходимые мне свойства.

    Теперь возникает другой вопрос: Как правильно выгрузить пакет BPL с немодальной формой внутри?
  • Игорь Шевченко © (19.02.08 12:36) [16]

    > Здесь указал... т.е. не сказал что динамически, но из кода
    > видно и так.


    Дорогой друг, у нас проблемы с переменными, пакетами и прочей фигней нету и нам ее решать не надо. Проблема есть у тебя и в твоих интересах не притворятся партизаном, попавшим в плен к злым гестаповцам и ни за что не желающим открыть врагу военную тайну.


    > Теперь возникает другой вопрос: Как правильно выгрузить
    > пакет BPL с немодальной формой внутри?


    Да пофиг как выгружать. Если у тебя при выгрузке какие-то проблемы, то нехреново бы их здесь озвучить, если проблем нету, то очевидно и спрашивать незачем, выгружай, как хочется и не мучайся.
  • Sirus (19.02.08 12:47) [17]
    Приношу свои извинения за "видно итак" :)

    Загружаю пакет
    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...

    Паралелльно есть ееще вопрос: Нужно чтобы при клике в меню форма создавалась только если ее нет, а если есть то просто отображалась (выходила на передний план).
  • Sirus (19.02.08 13:06) [18]
    Если сделать так
    Procedure TMainForm.WMFCDWorkers(var Msg: TMessage);
    Begin
    UnloadPackage(HM_R3DWorkers);
    End


    То ошибка пропадает, но возникает вопрос: Правильно ли это?
  • Sirus (19.02.08 13:07) [19]
    Если сделать так
    Procedure TMainForm.WMFCDWorkers(var Msg: TMessage);
    Begin
    DWorkersWFrm.Free;
    UnloadPackage(HM_R3DWorkers);
    End


    То ошибка пропадает, но возникает вопрос: Правильно ли это?
  • Sirus (19.02.08 13:11) [20]
    По моему все :)
    Тему можно считать закрытой
 
Конференция "Основная" » Переменные пакетов времени выполнения [D6, Win2k, WinXP]
Есть новые Нет новых   [134483   +43][b:0][p:0.002]