我已经阅读了Embarcadero和其他文档,在网上搜索了,显然没有发现问题。我有一个非常复杂的Application和DLL / Dylib,但是现在只是使用这个简单的示例来尝试获得它工作。当我为Win32构建应用程序和DLL时,它工作正常,并且如果我不对DLL进行函数调用,也可以正常工作。一旦我对DLL进行调用,就会出现错误:无法注册TFMXApplicationDelegate类,并且应用程序终止。无论访客操作系统是在VM(并行)上还是在物理设备上(2015年中的MacBook Pro 15),此行为都是相同的。
问题:如何确保 TFMXApplicationDelegate 已注册,是否需要设置或设置权限。根据Apple文档,这似乎相当基本:
应用程序委托实际上是应用程序的根对象。
DPR:
Library pTestDLL;
uses
uTestDLL in 'uTestDLL.pas';
{$R *.res}
end.
这是简单的PAS文件(用于Dylib):
unit uTestDLL;
interface
uses
FMX.Dialogs;
// External functions and procedures
{$IFDEF MSWINDOWS}
function say_Hello(Hello: string): boolean; stdcall; forward;
{$ENDIF MSWINDOWS}
{$IFDEF MACOS}
function _say_Hello(Hello: string): boolean; cdecl; forward;
{$ENDIF MACOS}
exports
{$IFDEF MSWINDOWS}
say_Hello;
{$ENDIF MSWINDOWS}
{$IFDEF MACOS}
_say_Hello;
{$ENDIF MACOS}
Implementation
{$IFDEF MSWINDOWS}
function say_Hello(Hello: string): boolean; stdcall;
{$ENDIF MSWINDOWS}
{$IFDEF MACOS}
function _say_Hello(Hello: string): boolean; cdecl;
{$ENDIF MACOS}
begin
Result := True;
showmessage('In DLL: ' + Hello);
end;
end.
最后是简单的测试应用程序:
unit uDylibTest1;
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;
const
// Windows DLL Names
{$IFDEF MSWINDOWS}
TestDLL = 'pTestDLL.dll';
{$ENDIF MSWINDOWS}
// macOS DYLIB Names
{$IFDEF MACOS}
TestDLL = 'libpTestDLL.dylib';
{$ENDIF MACOS}
type
TfDylibTest = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TuDylibTest = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
{$IFDEF MSWINDOWS}
function say_Hello(Hello: string): boolean; stdcall; external TestDLL Delayed;
{$ENDIF MSWINDOWS}
{$IFDEF MACOS}
function _say_Hello(Hello: string): boolean; cdecl; external TestDLL;
{$ENDIF MACOS}
var
fDylibTest: TfDylibTest;
implementation
{$R *.fmx}
procedure TfDylibTest.Button1Click(Sender: TObject);
var
b:boolean;
begin
showmessage('B4 function call);
b := False;
// Call the DLL Function
{$IFDEF MSWINDOWS}
b := say_Hello('The string passed to the DLL') then
{$ENDIF MSWINDOWS}
{$IFDEF MACOS}
b := _say_Hello('The string passed to the DLL');
{$ENDIF MACOS}
if b then
showmessage('Say Hello OK')
else
showmessage('Say Hello Failed');
end;
procedure TfDylibTest.FormCreate(Sender: TObject);
begin
showmessage('onCreate');
end;
procedure TfDylibTest.FormShow(Sender: TObject);
begin
showmessage('onShow');
end;
end.
答案 0 :(得分:0)
我代表亚历山大·布拉兹达·洛佩斯(Alexander BrazdaLópez)回答了这个问题,亚历山大·布拉兹达·洛佩斯(Alexander BrazdaLópez)在G + Delphi论坛上发布了此信息(因此,我不相信别人的回答):
ShowMessage()在dll中使用FMX.Dialogs。我记得有一些 有关此方面的限制,建议使用bpl代替dll。我会 尝试找到有关此的一些信息。仅作检查,请尝试使用 reversestring函数用于测试打开并调用dll函数 工作。
我无法评论WRT回应的下一部分的真实性,但为了公平起见,我们将对此进行评论。但是最重要的是,在uses子句中使用了FMX.Dialogs或FMX.Forms时,出现了错误。删除那些,并且不会发生TFMXApplicationDelegate错误。
在非平凡的“真实”示例中,我将showmessage
和application.processmessages
的单位使用在名为WaitNoFreeze()
的跨平台函数中,顾名思义, ,在主线程中等待,但不会停止所有其他活动,例如sleep()
。
问题不是找不到dylib,可以通过以下方法检查 在dylib中调用基本函数作为函数sum(a,b:整数): 整数
问题是当我们通过某些功能或使用来调用UI时 嵌入式资源,例如表格。这是因为如果我们不使用 bpl,将创建本地实例而不是共享的全局实例, 这样可以防止诸如RegisterClass或GetMem之类的功能共享 数据。在FMX的情况下,由于 在Windows中,Kevin公开的示例 窗口不是必需的,因此0是有效值,在MacOSX中为 必要,但dynlib中的值为NULL,因为尚未 启动,虽然在应用程序中,但是因为FMX实例 不共享,则无法访问此信息。它是 当我们尝试释放内存中的一块内存时发生的同样的事情 Windows已由应用程序分配的dll,这就是为什么 我们必须使用bpl,以便应用程序的内存管理器和 dll是相同的,并且无论如何都维护相同的实例 是否从dll或exe调用它们的方法