Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从C++;显示表单时崩溃_C++_Delphi_Forms_Dll_Crash - Fatal编程技术网

C++ 从C++;显示表单时崩溃

C++ 从C++;显示表单时崩溃,c++,delphi,forms,dll,crash,C++,Delphi,Forms,Dll,Crash,编辑:愚蠢的问题,已修复 Frime是代码> nIL/COD>因为我没有给它分配新的 TFrim1,我忘了Delphi不象C++那样为你做这件事。 我有一个Delphi DLL,我想用它来C++程序的GUI,所以对于初学者,我创建了一个表单,并有一个函数,它显示了导出的表单,以便C++调用它。但是,程序在调用函数时崩溃。这是我的密码。(我正在使用Delphi 2010) 德尔菲部分: unit Main; interface uses Windows, Messages, SysUtil

编辑:愚蠢的问题,已修复<代码> Frime是代码> nIL/COD>因为我没有给它分配新的<代码> TFrim1,我忘了Delphi不象C++那样为你做这件事。 <>我有一个Delphi DLL,我想用它来C++程序的GUI,所以对于初学者,我创建了一个表单,并有一个函数,它显示了导出的表单,以便C++调用它。但是,程序在调用函数时崩溃。这是我的密码。(我正在使用Delphi 2010)

德尔菲部分:

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;

程序打印“找到它”,然后崩溃。如果我在Delphi DLL中注释掉
Form1.Show()
,它不会崩溃,函数返回3(由printf测试)。我是否缺少一些初始化或什么?谢谢。

它崩溃的原因是
变量Form1:TForm1未初始化

var形成1:TForm1的原因未初始化,很可能是因为您将
单元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;
此外,您应该在
ShowForm
函数实现的周围放置一个
try…块,如下所示

您可能也应该做类似的事情来释放其他可能分配的动态内存


--杰伦

jeroen,回答得很好,但OP已经得出了这个结论并编辑了Q so!我的答案中有两个重要的东西不在他的编辑中:是try/except块,还有应用程序的释放。@Jeroen我不明白你为什么调用
ProcessMessages
,我看不到释放应用程序的理由。我记得我看过一个项目,其中需要ProcessMessages,因为表单在销毁时做了一些愚蠢的事。应用实例在第一次访问时自动创建,因此需要销毁;DLL本身不会这样做。@Jeroen如果要在应用程序中显示DLL中创建的表单,他需要自己运行消息循环。我从来没有感到舒服泵我的主人的信息!应用程序对象在
控件中创建。InitControls
初始化调用。它在从
终结
调用的匹配例程
DoneControls
中被销毁。你不应该释放它。