如何实现Delphi的ToolsAPI的IOTAProjectCompileNotifier?

时间:2011-03-26 01:03:13

标签: delphi toolsapi

我正在使用Delphi XE IDE。我创建了一个通知程序来实现IOTACompileNotifier。在IDE中安装专家后。编译项目时代码工作正常。通知程序正在为ProjectCompileStarted工作。

第二次编译我的项目时,Delphi IDE提示符:

[Fatal Error] Access violation at address 21B7FBED in module 'delphicoreide150.bpl'. Read of address 00000000

虽然我表现得很奇怪:

var i: integer;
begin
  i := Project.ProjectBuilder.AddCompileNotifier(TProjectCompileNotifier.Create);
  Project.ProjectBuilder.RemoveCompileNotifier(i);
end;
发号人中的

。我只是想显示ProjectBuilder的Add and Remove编译通知程序似乎无法正常运行,无论我如何使用。

请告知我应该如何实施IOTAProjectCompileNotifier。

谢谢。

以下是完整的源代码:

type
  TProjectCompileNotifier = class(TInterfacedObject, IOTAProjectCompileNotifier)
  protected
    procedure AfterCompile(var CompileInfo: TOTAProjectCompileInfo);
    procedure BeforeCompile(var CompileInfo: TOTAProjectCompileInfo);
    procedure Destroyed;
  end;

  TCompileNotifier = class(TInterfacedObject, IOTACompileNotifier)
  protected
    procedure ProjectCompileStarted(const Project: IOTAProject; Mode: TOTACompileMode);
    procedure ProjectCompileFinished(const Project: IOTAProject; Result: TOTACompileResult);
    procedure ProjectGroupCompileStarted(Mode: TOTACompileMode);
    procedure ProjectGroupCompileFinished(Result: TOTACompileResult);
  end;

procedure TCompileNotifier.ProjectCompileStarted(const Project: IOTAProject;
  Mode: TOTACompileMode);
var i: integer;
begin
  i := Project.ProjectBuilder.AddCompileNotifier(TProjectCompileNotifier.Create);
  Project.ProjectBuilder.RemoveCompileNotifier(i);
end;

var i: integer;

initialization
  i := (BorlandIDEServices as IOTACompileServices).AddNotifier(TCompileNotifier.Create);
finalization
  (BorlandIDEServices as IOTACompileServices).RemoveNotifier(i);
end.

3 个答案:

答案 0 :(得分:4)

我想我可以回答这个问题。我没有XE,因此我似乎没有IOTAProjectCompileNotifier。但是,我的ToolsAPI单元中的其他AddNotifier方法表明它将被声明为:

function AddNotifier(const ANotifier: IOTAProjectCompileNotifier): Integer;

你这样称呼这个例程:

i := Project.ProjectBuilder.AddCompileNotifier(TProjectCompileNotifier.Create);

问题是没有任何内容引用TProjectCompileNotifier.Create返回的接口。你需要这样做:

procedure TCompileNotifier.ProjectCompileStarted(const Project: IOTAProject; Mode: TOTACompileMode);
var
  i: integer;
  Intf: IOTAProjectCompileNotifier;
begin
  Intf := TProjectCompileNotifier.Create;
  i := Project.ProjectBuilder.AddCompileNotifier(Intf);
  Project.ProjectBuilder.RemoveCompileNotifier(i);
end;

您需要在初始化/完成代码中也这样做。

我认为这应该被认为是接口引用计数实现中的一个错误。它已多次discussed here on Stack Overflow

答案 1 :(得分:3)

我想知道为什么你要从回调中删除你的通知程序。我可以想象OTA不能很好地处理这种情况。请尝试以下操作:首先(当加载并初始化包时)安装IOTAIDENotifier以在项目打开时通知(在完成时将其删除)。实现FileNotification以在项目打开时添加IOTAProjectCompileNotifier,在项目关闭时将其删除。

答案 2 :(得分:0)

错误代码“读取地址00000000”可能表示您正在尝试访问不存在的资源。我看到你在Embarcadero论坛上问了同样的问题。从我在这里看到的SO,只有几个开发者对OTA感兴趣,CG或Embarcadero的文档几乎不存在,所以我建议你坚持Embarcadero的论坛。

最好的问候,
拉杜