2

我希望我能体面地解释这个问题!

我正在尝试将 ReWire 音频设备实现为 Delphi .dll。如果您不知道 ReWire 是什么,请不要担心。重要的是我的代码编译成 .dll,我从 ReWire 系统调用我的 .dll 来打开显示器,检查显示器是否打开,然后再次关闭它。

当我接到启动电话时,我会执行以下操作:

  if not Assigned(form) then
    form := TMyForm.Create(nil);
  form.Show;

我的 Delphi 库form中的全局变量在哪里(可能有问题?)。我已经连接了MyForm's OnCreateevent 来做一些有趣的事情,比如准备一系列我想要使用的东西。

到目前为止一切都很好。我的表单中有一个小按钮,可以打开TOpenDialog. 我发现,一旦该对话框关闭,OnCreate事件就会以某种方式再次以我的形式触发!

我已经检查过OnDestroy没有被调用,所以我不知道为什么OnCreate会再次被调用。

不幸的是,我不太确定哪些信息是相关的,但这是第一次调用堆栈(首次设置表单时):

第一个调用栈

正如预期的那样,ReWire 正在调用我的 .dll 以启动 Panel 应用程序,因此我创建了我的表单。太好了,情况看起来不错。

然后在我的表单中,我打开一个小对话框,选择一个文件,然后进行一些操作。在左侧字段之外,OnCreate再次调用,这是当时的调用堆栈:

第二个调用栈

这是一个疯狂的电话聚会!Reaper(在底部)是我用来测试我的应用程序的 ReWire 主机,但我不知道堆栈跟踪内部发生了什么,因为它都不是我的代码。突然,当我认为不应该调用该事件时,该事件就被调用了,因为OnDestroy甚至没有调用该事件。

我能想到的唯一另一件重要的事情是,如果我打印出 的地址,Sender每次都不同,所以它会以某种方式再次创建或其他什么,但我已经检查过我只调用了 MyForm.Create 一次。

关于这种事情如何发生的任何想法?

4

2 回答 2

4

在第一个堆栈跟踪中,OnCreate调用之前是对 的调用TCustomForm.Create(),这是正确的行为。在第二个堆栈跟踪中,OnCreate调用之前是调用,TObject.Create()而不是正确的行为。这使我认为您的按钮OnClick事件处理程序中的某些内容要么正在构造具有错误 VMT 的对象,要么通常会破坏内存并导致错误地跳转到恰好被您的TForm类占用的代码中。无论哪种方式,请仔细检查您的OnClick逻辑是否存在错误。

于 2012-04-30T04:30:15.623 回答
1

检查(任何)将表单变量设置为零的位置。可能是它被设置为 nil 而没有释放它指向的表单,所以下次调用你的启动代码时,它会创建表单的另一个实例。

于 2012-04-30T02:50:48.667 回答