从 C++ 调用 Delphi DLL显示表单时崩溃
编辑:愚蠢的问题,已经解决了。 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测试)。我是否缺少一些初始化或其他东西?谢谢。
EDIT: Dumb question, already fixed. Form1
was nil
because I didn't assign it a new TForm1
, I forgot Delphi doesn't do that for you like C++.
I have a Delphi DLL that I want to use for the GUI of my C++ program, so just for starters, I created a form, and have a function that will show the form which is exported so that C++ can call it. However, the program crashes when it calls the function. Here is my code. (I am using Delphi 2010)
The delphi part:
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.
And here is the C++ code:
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;
The program prints "Found it @ " and then crashes. If I comment out Form1.Show()
in the Delphi DLL, it doesn't crash, and the function returns 3 (tested by printf). Am I missing some initialization or something? Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它崩溃的原因是
var Form1: TForm1;
未初始化。var Form1: TForm1;
未初始化的原因很可能是因为您将unit Main
放入了DLL项目中,但它最初来自Delphi VCL项目自动创建列表中有Form1
。自动创建列表意味着Delphi .dpr 将初始化表单。
现在您需要手动创建表单,因此您需要从 DLL 中导出这 3 个新例程,并让 C++ DLL 调用它们:
此外,您应该放置一个
try... except
块围绕ShowForm
函数实现的实现,如 异常和其他语言相关的运行时功能不应跨越 DLL 边界。您可能也应该执行类似的操作来释放其他可能分配的动态内存块。
——杰罗恩
The reason it crases is that the
var Form1: TForm1;
is not initialized.The reason that the
var Form1: TForm1;
is not initialized, is most likely because you put theunit Main
into a DLL project, but it originally came from a Delphi VCL project where you hadForm1
on the auto-creation list.The auto-creation list means that the Delphi .dpr will initialize the form.
Now you need to manually create the form, so you need to export these 3 new routines from your DLL, and have the C++ DLL call them:
In addition, you should put a
try...except
block around the implementation of yourShowForm
function implementation, as exceptions and other language dependent run-time features should not cross DLL boundaries.You probably should do similar things for releasing other potentially allocated pieces of dynamic memory too.
--jeroen