2016-07-13 24 views
2

アプリケーション全体のパブリックメソッドを修正する必要があります。自分自身でパブリックメソッドを置き換える必要がありますが、パッチメソッドから元のメソッドを呼び出すことはできます。パブリック非仮想メソッドへのパッチ適用

私は自分の方法でこのメソッドを置き換える方法を知っています。 How to change the implementation (detour) of an externally declared function

そして、ここでもう一つの例:Make Disabled Menu and Toolbar Images look better?

しかし、私にはわからないことは、元の最初の呼び出し方法です。例えば

// Store the original address of the method to patch 
var OriginalMethodBackup: TXRedirCode;  

// this is the implementation of the new method 
procedure MyNew_Method(Self: TObject; Index: Integer); 
begin 
    try 
    // some code here 
    call ORIGINAL public method here 
    finally 
    // some code here 
    end; 
end; 

EDIT:私は、Delphi迂回ライブラリを試してみましたが、それは文句を言わないD5とD7の下でコンパイルします。ポインタ演算、未知の型、クラスvars、未知のコンパイラ指令、未知のasm命令など、多くの問題があります。コードはD5とD7の両方をサポートするように移植されなければなりません。私は今までにほとんどの移植を行ってきましたが、まだいくつかの問題に取り組んでいます。いずれにせよ、私はそれが完了した後にそれが正しく働くかどうか分からない。代替案が必要になるかもしれない。

+0

その方法は仮想ですか? –

+0

@ Arioch'The、それは仮想ではありません – zig

答えて

3

非仮想メソッドを変更する場合は、メソッドにパッチを適用する必要があります。

あなたはDelphi Detours libraryを使用してルーチンにパッチを適用することができます

type 
    TMyMethod = procedure(Self: TObject; Index: Integer); 

var 
    OldMethod: TMyMethod; //make sure to initialize to nil. 

procedure MyNewMethod(Self: TObject; Index: Integer); 
begin 
    Assert(Assigned(OldMethod),'Error: MyMethod is not hooked'); 
    //If you need to call the OldMethod you can use the variable. 
    OldMethod(Self, Index); 
    //Do additional stuff here 
    ShowMessage('New stuff'); 
end; 

procedure DoHook; 
begin 
    @OldMethod:= InterceptCreate(@MyOriginalMethod, @MyNewMethod); 
end; 

procedure RemoveHook; 
begin 
    if Assigned(OldMethod) then 
    begin 
    InterceptRemove(@OldMethod); 
    OldMethod := nil; 
    end; 
end; 

ウィキへのリンクをDDetours is hereため。

このメソッドにはパッチが適用されますが、OldMethodを呼び出して元のメソッドにアクセスすることができます。

+0

ありがとう、私はDDetoursのlibを使用できない場合はどうしますか? (例えば私のD5アプリケーションで)。すでに使用しているパターンに基づいて何かができるのでしょうか? – zig

+0

D7をあなたのバージョンとして挙げましたが、それ以外はDet5がD5でうまくいきます。 – Johan

+0

D5では動作しません。私はちょうどそれをテストした。私があなたの答えを受け入れる他の解決策がなければ、最初のコードに基づいた解決策を本当に望んでいました。 – zig

0

私にまっすぐ進むようだ:

  • 元に戻すパッチ
  • 呼び出し方法
  • は再びパッチを適用

編集:他の人が指摘したように、これが唯一の有効なアプローチであります単一のスレッドで使用するためのものです。

+2

これは実際にはあまり良いアドバイスではありません。なぜなら、そのようなアプローチではスレッドの安全性が低下するからです。 –

+0

これは悪い考えです。私にはOPがパッチされたメソッドの中で古いメソッドを呼び出すと思われるからです。 – Johan

+0

@Johan、私はUweが(疑似)と言っていると思う: 'RemoveHook;コールメソッド。 DoHook; ** **パッチされたメソッドの内部**。これは実際に動作します。しかし私はそれが安全であるとは確信していません。毎回パッチを元に戻したり適用したりせずに、パッチメソッド内で 'OriginalMethodBackup:TXRedirCode'を何とか呼び出すことはできませんか? – zig

関連する問題