CodeZine(コードジン)

特集ページ一覧

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

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

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2010/02/22 14:00

ダウンロード 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(クラスインスタンス)と、クラスのインスタンスを渡す必要があります。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

修正履歴

  • 2010/02/23 13:15 -Wno-pmf-conversionsオプション関連の一文を削除しました。

  • 2010/02/14 21:59 最新版では-Wno-pmf-conversionsが不要になりました。 gccバージョンを書きました。

バックナンバー

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

著者プロフィール

  • rti(あーるてぃーあい)

    働いたら負けだと思っていた元ニートのプログラマ 歌って踊れてさくらたんにもハァハァできます。 love:C++,アセンブラ,PHP,javascript好きのOO厨房 低レイヤープログラムやネットワークサーバからサーバサイドプログラム、ソフトウェア設計、インフラ設計運用までと幅広くやってます。...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5