Перейти к содержанию
Fire Monkey от А до Я
  • 0

Вызов Формы FMX из dll


Евгений Деревянкин

Вопрос

Добрый день! помогите с решением, нужен модуль с формой который будет работать на FMX и VCL. Был сделан выбор на использование библиотек DLL. В библиотеке находится TForm и TDataModule. На форме отображается данные из выполненного запроса, добавление, редактирование, удаление записей. Во время вызова формы в DLL передаем строку подключения и подключаемся к БД. на Windows все прекрасно работает, библиотека вызывается на FMX и VCL, из dll отображается форма и загружает данные из БД, все работает. Но есть проблема когда я собираю эту же библиотеку на Android во время создания формы или фрейма вылетает AV.  Даже просто вызываю из DLL функцию Showmessage на Android получаю AV. Пробовал передать в библиотеку TAndroidHelper.Context и вызвать из нее TJToast и все равно AV. Обычные функции с возвращение какого либо значения прекрасно работают, а как доходит дело работы с интерфейсом тут же получаю AV. 

Подскажите есть ли возможность заставить все это работать на Android. Было бы прекрасно использовать одну библиотеку в разных проектах. Заранее Спасибо!

 

library Lib;

uses
  System.SysUtils,
  System.Classes,
  Fmx.Types,
  FMX.Dialogs,
  Un_dm in 'lib\Un_dm.pas' {dm: TDataModule},
  Un_FormFMX in 'lib\Un_FormFMX.pas' {FormFMX},
  Un_FrameFMX in 'lib\Un_FrameFMX.pas' {FrameFMX: TFrame};

{$R *.res}

const
  DLL_PROCESS_ATTACH = 1;
  DLL_PROCESS_DETACH = 0;

procedure DLLMain(dwReason: integer);
begin
  case dwReason of
  DLL_PROCESS_ATTACH:
    begin
      Dm:=TDm.Create(nil);
    end;

  DLL_PROCESS_DETACH:
    begin
      FreeAndNil(dm);
      if assigned(FormFMX) then
         FreeAndNil(FormFMX);
    end;
  end;
end;


procedure CreateFormFMX(connect:string);
begin
  dm.UniConnection1.ConnectString:=connect;
  FormFMX:=TFormFMX.Create(nil);
  FormFMX.Show;
end;

procedure CreateFrameFMX(AOwner:TComponent;Parent:TFMXObject;connect:string);
begin
  FrameFmx:=TFrameFMX.Create(AOwner);
  FrameFmx.Parent:=Parent;
end;


exports CreateFormFMX, CreateFrameFMX;

begin
  DLLProc := @DLLMain;
  DLLMain(DLL_PROCESS_ATTACH);
end.

Вызов библиотеки:

unit Un_MainFmx;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Controls.Presentation, FMX.Edit, FMX.Layouts;

type
  TMain = class(TForm)
    Layout1: TLayout;
    Edit1: TEdit;
    Label1: TLabel;
    Button1: TButton;
    Button2: TButton;
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Main: TMain;

implementation

{$R *.fmx}

uses
{$IF DEFINED(win32) or DEFINED(win64)}
    WinApi.Windows,
{$ENDIF}
    System.IOUtils;

var
  LibHandle: THandle;
  CreateFormFMX: procedure(connect:string);
  CreateFrameFMX: procedure(AOwner:TComponent;Parent:TFMXObject;connect:string);


Function LoadLib(Name:string):THandle;
var dll:THandle;
    Path: string;
begin
{$IF DEFINED(win32) or DEFINED(win64)}
  result:= LoadLibrary(PChar(Name+'.dll'));
{$ENDIF}
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
  Path := IncludeTrailingPathDelimiter(TPath.GetLibraryPath);
  result := LoadLibrary(PChar(Path + 'lib' + name + '.so'));
{$ENDIF}
end;

procedure TMain.FormCreate(Sender: TObject);
begin
  LibHandle := LoadLib('Lib');
end;

procedure TMain.FormDestroy(Sender: TObject);
begin
 FreeLibrary(LibHandle);
end;

procedure TMain.Button1Click(Sender: TObject);
begin
 @CreateFormFMX := nil;

 if LibHandle >= 32 then
 begin
    @CreateFormFMX := GetProcAddress(LibHandle,'CreateFormFMX');
    if @CreateFormFMX <> nil then
       begin
        CreateFormFMX(Edit1.Text);
       end;
 end;
end;

procedure TMain.Button2Click(Sender: TObject);
begin
 @CreateFrameFMX := nil;

 if LibHandle >= 32 then
 begin
    @CreateFrameFMX := GetProcAddress(LibHandle,'CreateFrameFMX');
    if @CreateFrameFMX <> nil then
       begin
        CreateFrameFMX(panel1,panel1,Edit1.Text);
       end;
 end;
end;


end.

 

Debug.rar

Project.rar

Изменено пользователем Евгений Деревянкин
Ссылка на комментарий

Рекомендуемые сообщения

  • 0

я думаю так не получиться. можно попробовать сделать так чтобы длл формировала нужную форму, например в json, а главная форма приложения уже разбирала его и показывала форму на его основе. 

Изменено пользователем haword
Ссылка на комментарий
  • 0

Визуальный интерфейс да, можно формировать динамически, например на основе json

Тут проблема в другом, как реализовать произвольные обработчики логики в этой динамической форме. Либо извращаться и передавать обработчики в эту dll/so, либо использовать какой нибудь парсер

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...