Добрый день! помогите с решением, нужен модуль с формой который будет работать на 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.
Вопрос
Евгений Деревянкин
Добрый день! помогите с решением, нужен модуль с формой который будет работать на 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
Изменено пользователем Евгений ДеревянкинСсылка на комментарий
4 ответа на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.