【问题标题】:FMX form in a DLL (firemonkey/delphi)DLL 中的 FMX 形式(firemonkey/delphi)
【发布时间】:2012-01-01 23:16:37
【问题描述】:

我试图在 dll 中制作 FMX 表单,大约 17 小时后(尝试不同的方法)我让它工作了,除了我在尝试卸载 dll 时遇到异常。我不知道如何使它工作,也许有人可以帮助我并指出我做错了什么?

旁注: 由于 AA 绘图,我的 VCL 应用程序中不能有 FMX 表单,我只需要在画布上绘制时在我的文本上使用它,而在 VCL 应用程序上使用 FMX 表单时,我在文本上没有得到清晰的类型 :( 我正在尝试制作某种 OSD/HUD。

项目显示我的问题:

exe unit1.pas

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  unitLoadDLL, Winapi.GDIPOBJ;

procedure TForm1.Button1Click(Sender: TObject);
begin
  showme();
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  closeme();
end;

end.

exe unitLoadDll.pas

unit unitLoadDLL;

interface

uses Windows, Dialogs;

type
  TShowme = procedure();
  TCloseme = procedure();

var
  showme : TShowme = nil;
  closeme : TCloseme = nil;
  DllHandle : THandle;

implementation

initialization

  if DllHandle = 0 then begin
    DllHandle := LoadLibrary('C:\Users\Ja\Desktop\dupa\dll\Win32\Debug\Project1.dll');
    if DllHandle > 0 then begin
      @showme := GetProcAddress(DllHandle,'showme');
      @closeme := GetProcAddress(DllHandle,'closeme');
    end
    else begin
      MessageDlg('Select Image functionality is not available', mtInformation, [mbOK], 0);
    end;
  end;

finalization
  if DLLHandle <> 0 then
    FreeLibrary(DLLHandle);
end.

dll project1.dpr

library Project1;


uses
  FMX.Forms,
  System.SysUtils,
  System.Classes,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

procedure showme(); stdcall export;
begin
  TForm1.showme;
end;

procedure closeme(); stdcall export;
begin
  TForm1.closeme;
end;

exports
  showme, closeme;

begin
end.

dll unit1.pas

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs;

type
  TForm1 = class(TForm)
    Label1: TLabel;
  private
    { Private declarations }
  public
    class procedure showme();
    class procedure closeme();
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

class procedure TForm1.showme();
begin
  Form1 := TForm1.Create(Application);
  Form1.Show;
end;

class procedure TForm1.closeme();
begin
  Form1.Free;
end;

end.

编辑(修复):

所有答案都有帮助,但我所做的是,在 dll 卸载之前 GDI+ 已关闭...这似乎是问题所在。

新的 unitLoadDll.pas

unit unitLoadDLL;

interface

uses Windows, Dialogs;

type
  TShowme = procedure();
  TCloseme = procedure();

var
  showme : TShowme = nil;
  closeme : TCloseme = nil;
  DllHandle : THandle;

  function LoadLib : Boolean;
  procedure UnloadLib;

implementation

function LoadLib : Boolean;
begin
  if DllHandle = 0 then begin
    DllHandle := LoadLibrary('C:\Users\Ja\Desktop\dupa\dll\Win32\Debug\Project1.dll');
    if DllHandle > 0 then begin
      @showme := GetProcAddress(DllHandle,'showme');
      @closeme := GetProcAddress(DllHandle,'closeme');
    end
    else begin
      MessageDlg('Select Image functionality is not available', mtInformation, [mbOK], 0);
    end;
  end;
  Result := DllHandle <> 0;
end;

procedure UnloadLib;
begin
  if DLLHandle <> 0 then begin
    FreeLibrary(DLLHandle);
    DllHandle := 0;
  end;
end;

initialization
  LoadLib;

finalization
  UnloadLib;
end.

新的 unit1.pas

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Winapi.GDIPOBJ;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  unitLoadDLL;

procedure TForm1.Button1Click(Sender: TObject);
begin
  showme();
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  closeme();
end;

end.

在 unit1.pas 中,我将 Winapi.GDIPOBJ 移到 interface 指令之后的“uses”,并且它起作用了...

谢谢大家的回答!再见!很快……

【问题讨论】:

标签: delphi dll firemonkey


【解决方案1】:

两边都导入sharemem有用吗?

您没有使用包,因此双方可能都有自己的所有 RTL 状态的实例,以及 VMT 表(尽管这只是某些 IS 和 AS 情况的问题)。并且内存管理器是 RTL 状态:-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 2017-06-28
    • 2012-05-22
    • 1970-01-01
    相关资源
    最近更新 更多