Невозможно зарегистрировать класс TFMXApplicationDelegate - PullRequest
0 голосов
/ 24 сентября 2018

Я читал Embarcadero и другие документы, искал в сети, и, очевидно, что-то не тонет. У меня есть значительно более сложные приложения и DLL / Dylib, но сейчас я просто использую этот простой пример, чтобы попытаться получитьэто на работу.Когда я собираю приложение и DLL для Win32, оно работает нормально и работает нормально, если я не выполняю вызов функции для DLL.Как только я звоню в DLL, возникает ошибка «Невозможно зарегистрировать класс TFMXApplicationDelegate», и приложение завершается.Это поведение одинаково, независимо от того, установлена ​​ли гостевая ОС на виртуальной машине (Parallels) или на физическом устройстве (MacBook Pro 15, середина 2015 г.).

ВОПРОС: Как убедиться, что 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 голосов
/ 13 октября 2018

Я отвечаю на это от имени Александра Бразды Лопеса, который разместил это на форуме G + Delphi (так что я не берусь за чужой ответ):

ShowMessage () использует FMX. Диалоги внутри DLL.Я помню, что были некоторые ограничения по этому поводу, и вместо этого рекомендовалось использовать bpl.Я бы попытался найти информацию об этом.Просто для проверки, попробуйте использовать функцию обратной строки для открытия теста и вызова функций dll.

Я не могу прокомментировать WRT правдивость следующей части ответа, но, если честно, включу ее,Однако суть в том, что с FMX.Dialogs или FMX.Forms в предложении использования я получил ошибку.Удалите их, и ошибка TFMXApplicationDelegate не возникла.

В нетривиальном «реальном» примере я использовал единицу для showmessage и для application.processmessages, которая была в кроссплатформенной функции под названием WaitNoFreeze(), которая, как следует из названия, помещаетожидание в главном потоке, но не останавливает все остальные действия, такие как sleep().

Проблема не в том, что dylib не найден, это можно проверить, вызвав базовую функцию в dylibкак функция sum (a, b: integer): integer

Проблема в том, что мы вызываем пользовательский интерфейс через какую-то функцию или используем встроенные ресурсы, такие как формы.Это связано с тем, что если мы не используем bpl, вместо общих глобальных экземпляров создаются локальные экземпляры, это препятствует совместному использованию данных такими функциями, как RegisterClass или GetMem.В случае FMX есть различия из-за API для примера, который выставил Кевин, в Windows дескриптор окна не требуется, поэтому 0 является допустимым значением, в MacOSX это необходимо, но значение в dynlibNULL, поскольку он не был запущен, хотя в приложении, но поскольку экземпляры FMX не являются общими, доступ к этой информации невозможен.То же самое происходит, когда мы пытаемся освободить блок памяти в dll в окнах, выделенных приложением, поэтому мы должны использовать bpl, чтобы менеджер памяти приложения и dll былиодинаковые и поддерживают одинаковые экземпляры независимо от того, вызваны ли их методы из dll или из exe

...