SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

「SEXYHOOK」 とある関数の接合部

SEXYHOOKで始めるテスト
とある関数の接合部(1)

既存のソースコードに手を加えず、自由に接合部を作成

ダウンロード sexyhook0.8 (80.0 KB)

クラスメソッドをフックしたい場合

class testclass2
{
public:
        bool check()
        {
                if (this->checkCore(1))
                {
                        return true;
                }
                else
                {
                        //ここのテストがしたい
                        return false;
                }
        }
        bool checkCore(int a ) // ←これをフックする
        {
                return a ? true : false;
        }
};

//クラスメソッドの場合は SEXYHOOK_CLASS_HOOK_1_BEGIN を使ってください。
SEXYHOOK_CLASS_HOOK_1_BEGIN(bool,testclass2::checkCore,int a)
{
        return false;
}
SEXYHOOK_CLASS_END();

testclass2 myclass2;
bool r = myclass2.check();      //FALSE になる。

 書式は、次のようになります。

SEXYHOOK_CLASS_HOOK_引数の数_BEGIN(戻り値,メソッド名,引数....)
{
        フックする処理
        return 返却したい値;
}
SEXYHOOK_CLASS_END();

 メソッド名は「クラス::メソッド名」と定義してください。

オペレータをフックしたい場合

 オペレータオーバーロードもフックすることが可能です。

//オペレータオーバーロードのテスト
class OpClass
{
        int A;
public:
        OpClass(int inA) : A(inA)
        {
        }
        int getA() const
        {
                return this->A;
        }

        OpClass operator+( const OpClass& x )
        {
                OpClass z( this->A + x.A );
                return z;
        }

};

//演算子オーバーロードのテスト
{
        OpClass a(10);
        OpClass b(20);
        //フック関数を定義する前だからフックされない
        OpClass c = a + b;

        //ここからフック
        SEXYHOOK_CLASS_HOOK_1_BEGIN(OpClass,OpClass::operator +,const OpClass& x)
        {
                OpClass z( 1000 );
                return z;
        }
        SEXYHOOK_CLASS_END();

        //これはフックされる.
        OpClass d = a + b;
        SEXYHOOK_ASSERT(c.getA() == 30);
        SEXYHOOK_ASSERT(d.getA() == 1000);      //固定値
}

テンプレートをフックしたい場合

 テンプレートも同じです。

//これをフックしたい
template<typename _T> class TempTest
{
public:
        int add(_T a,_T b)
        {
                return a + b;
        }
};

{
        int r;

        TempTest<int> t;
        //ここからフック
        SEXYHOOK_CLASS_HOOK_2_BEGIN(int,TempTest<int>::add,int a,int b)
        {
                return a - b;   //足し算を引き算に書き換える
        }
        SEXYHOOK_CLASS_END();

        r = t.add(1,2);
        printf("\r\nテンプレートクラスのテスト\r\n");
        printf("TempTest<int> : %d //足し算を引き算に\r\n",r);
        SEXYHOOK_ASSERT(r == -1);
}

仮想関数をフックしたい場合

 仮想関数だけ少し特殊です。

class Parent
{
public:
        virtual int f()
        {
                return 1;
        }
        virtual int g() =0;
};

class Child : public Parent
{
public:
        int aaa()
        {
                return 0;
        }
        virtual int f()
        {
                return 2;
        }
        virtual int g()
        {
                return 3;
        }
};

{
        Child child;

        //ここからフック
        SEXYHOOK_CLASS_HOOK_0_BEGIN(int,Child::g)
        {
                return 103;     //Child::g
        }
        SEXYHOOK_CLASS_END_VCALL(child);        //VCALL


        int cg = child.g();
        SEXYHOOK_ASSERT(cg == 103);
}

 普通は、SEXYHOOK_CLASS_END()で終わりますが、仮想関数はSEXYHOOK_CLASS_END_VCALL()で終わらなければなりません。また、SEXYHOOK_CLASS_END_VCALL(クラスインスタンス)と、クラスのインスタンスを渡す必要があります。

次のページ
フックのまとめ

修正履歴

この記事は参考になりましたか?

「SEXYHOOK」 とある関数の接合部連載記事一覧
この記事の著者

rti(あーるてぃーあい)

働いたら負けだと思っていた元ニートのプログラマ歌って踊れてさくらたんにもハァハァできます。love:C++,アセンブラ,PHP,javascript好きのOO厨房低レイヤープログラムやネットワークサーバからサーバサイドプログラム、ソフトウェア設計、インフラ設計運用までと幅広くやってます。多分設計信者。 あんまり得意ではないけど 人工知能(学習エンジン)とかシステム...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4882 2010/02/23 13:15

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー