编辑:愚蠢的问题,已经修复。 Form1
是nil
,因为我没有为它分配一个新的TForm1
,我忘了Delphi并不像C ++那样为你做这件事。
我有一个Delphi DLL,我想用于我的C ++程序的GUI,所以对于初学者,我创建了一个表单,并且有一个函数将显示导出的表单,以便C ++可以调用它。但是,程序在调用函数时崩溃。这是我的代码。 (我正在使用Delphi 2010)
delphi部分:
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Tabs, ComCtrls;
type
TForm1 = class(TForm)
TabControl1: TTabControl;
TabSet1: TTabSet;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
function ShowForm(i: Integer) : Integer; export; cdecl;
exports
ShowForm name 'ShowForm';
implementation
{$R *.dfm}
function ShowForm(i: Integer) : Integer; export; cdecl;
begin
Form1.Show();
Result := 3; // random value, doesn't mean anything
end;
end.
这是C ++代码:
HMODULE h = LoadLibrary("delphidll.dll");
if (!h) {
printf("Failed LoadLibrary (GetLastError: %i)\n", GetLastError());
return 0;
}
FARPROC p = GetProcAddress(h, "ShowForm");
if (p)
printf("Found it @ %p\n", p);
else
printf("Didn't find it\n");
((int(__cdecl *)(int))p)(34);
system("PAUSE");
return 0;
程序打印“Found it @”然后崩溃。如果我在Delphi DLL中注释Form1.Show()
,它不会崩溃,并且函数返回3(由printf测试)。我错过了一些初始化或什么?感谢。
答案 0 :(得分:2)
它失败的原因是var Form1: TForm1;
未初始化。
var Form1: TForm1;
未初始化的原因很可能是因为您将unit Main
放入DLL项目中,但最初来自Delphi VCL项目Form1
在自动创建列表中。
自动创建列表意味着Delphi .dpr将初始化表单。
现在您需要手动创建表单,因此您需要从DLL中导出这3个新例程,并让C ++ DLL调用它们:
function CreateForm() : Integer; export; cdecl;
begin
try
Application.CreateForm(TForm1, Form1);
Result := 0;
except
Result := -1;
end;
end;
function DestroyForm() : Integer; export; cdecl;
begin
try
if Assigned(Form1) then
begin
FreeAndNil(Form1);
Application.ProcessMessages();
end;
Result := 0;
except
Result := -1;
end;
end;
function DestroyApplication() : Integer; export; cdecl;
begin
try
FreeAndNil(Application);
Result := 0;
except
Result := -1;
end;
end;
此外,您应该在try...except
函数实现的实现周围添加ShowForm
块,作为exceptions and other language dependent run-time features should not cross DLL boundaries。
你可能也应该做同样的事情来释放其他可能分配的动态内存。
- 的Jeroen