无法注册类TFMXApplicationDelegate

时间:2018-09-24 02:18:58

标签: macos delphi firemonkey delphi-10.2-tokyo

我已经阅读了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.

1 个答案:

答案 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错误。

在非平凡的“真实”示例中,我将showmessageapplication.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调用它们的方法