C++Builder XEでTVirtualMethodInterceptorを使ってみたが、解放時に「access violation」エラーが発生する。

TObjectに対してTVirtualMethodInterceptorでインターセプトするしたときは問題は発生しない。

TObjectの派生クラスに対してTVirtualMethodInterceptorでインターセプトすると解放時に「access violation」エラーが発生する。

以下、検証に使用したコード。

準備として、メソッドが実行される前に実行する処理を用意する

//メソッドが実行される前に実行する処理
#include <Rtti.hpp>
class TOnBefore : public TCppInterfacedObject<TInterceptBeforeNotify>
{
public:
  virtual void __fastcall Invoke(System::TObject* Instance, TRttiMethod* Method,
    const System::DynamicArray<TValue> Args, bool &DoInvoke, TValue &Result)
  {
    std::wcout << Method->Name.c_str() << std::endl;
  }
};

TObjectを動的にインターセプトする。このときは問題発生しない。

void P1()
{
  TObject* obj = new TObject();
  TVirtualMethodInterceptor* vmi = new TVirtualMethodInterceptor(obj->ClassType());
  vmi->OnBefore = new TOnBefore();
  vmi->Proxify(obj);
  obj->ToString();
  delete obj;
  delete vmi;
}

実行結果

ToString
BeforeDestruction
FreeInstance

TStringListを動的にインターセプトする。解放時にエラーが発生する。

void P2()
{
  TStringList* obj = new TStringList();
  TVirtualMethodInterceptor* vmi = new TVirtualMethodInterceptor(obj->ClassType());
  vmi->OnBefore = new TOnBefore();
  vmi->Proxify(obj);
  obj->ToString();
  delete obj; // <= access violation
  delete vmi;
}

実行結果

Add
AddObject
BeforeDestruction
FreeInstance

追記

他の方の環境ではエラーは発生しないそうです。

追記

環境を変えたらエラー発生しませんでした。
エラーの原因は不明です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください