2

DelphiXEIDEを使用しています。IOTACompileNotifierを実装するための通知機能を作成します。エキスパートをIDEにインストールした後。プロジェクトをコンパイルすると、コードは正常に機能します。通知機能はProjectCompileStartedで機能しています。

プロジェクトを2回目にコンパイルすると、DelphiIDEプロンプトが表示されます。

[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のコンパイル通知機能の追加と削除がどのように使用しても正しく機能していないように見えることを示したいだけです。

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.
4

3 に答える 3

4

多分これで答えられると思います。私は XE を持っていないので、持っていないようIOTAProjectCompileNotifierです。ただし、AddNotifierToolsAPI ユニットの他のメソッドは、次のように宣言されることを示唆しています。

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;

初期化/ファイナライズ コードでも同様に行う必要があります。

これは、インターフェイスの参照カウントの実装におけるバグと考えるべきだと思います。ここ Stack Overflow で何度も議論されています。

于 2011-03-26T11:09:34.517 に答える
3

コールバック内から通知機能を削除するのはなぜだろうか。シナリオが OTA によってうまく処理されていないことは想像に難くありません。次のことを試してください: 最初に (パッケージがロードされて初期化されるとき)、プロジェクトが開かれたときに通知されるように IOTAIDENotifier をインストールします (ファイナライズで削除します)。その FileNotification を実装して、プロジェクトが開いているときに IOTAProjectCompileNotifier を追加し、閉じているときに削除します。

于 2011-03-26T11:29:08.123 に答える
0

エラー コード「アドレス 00000000 の読み取り」は、存在しないリソースにアクセスしようとしていることを示している可能性があります。Embarcadero フォーラムで同じ質問をしたことがわかりました。私がここ SO で見たものから、OTA に興味を持っている開発者は数人しかおらず、CG や Embarcadero からのドキュメントはほとんど存在しないため、Embarcadero のフォーラムを主張することをお勧めします。

よろしく、
ラドゥ

于 2011-03-26T10:35:54.290 に答える