1

C++ では、メンバー関数のアドレスを取得することで関数ポインターを簡単に作成できます。しかし、そのローカル関数のアドレスを変更することは可能ですか?

つまり、同じクラスに funcA() と funcB() があり、定義が異なるとします。funcA() のアドレスを funcB() のアドレスに変更して、実行時に funcA() を呼び出すと実際に funcB() が呼び出されるようにしようとしています。私はこれが醜いことを知っていますが、私はこれを行う必要があります、ありがとう!

編集 - - - - -

私がやろうとしていることの背景:

既存のコード ベースの単体テストを実装したいと考えています。すべてのモジュールが継承している基本クラスのメソッドの一部は非仮想です。製品コードを編集することは許可されていません。ビルドプロセスをいじって、関連するメソッドを仮想に設定した基本クラスに置き換えることができますが、このようなハックを使用したいと思いました(可能だと思いました)。

また、私は技術的な好奇心からこのトピックに興味があります。この問題をハックしようとするプロセスを通じて、コード生成や関数検索などの仕組みが内部でどのように機能するかについてかなりのことを学んでいるからです。大学2年を終えたばかりで、学校で学ぶ機会がありませんでした。私はCSではなくコンピュータ工学プログラムにいるので、学校でそのようなことを教えられるかどうかはわかりません.

トピックに戻る メソッド funcA() と funcB() は確かに同じ署名を持っているため、問題は & 演算子を使用して関数のアドレスしか取得できないことです? 関数のアドレスを変更したり、メモリの一部を破損することなくそのアドレスの内容をスワップアウトしたりできないというのは正しいでしょうか? 関数が dll にエクスポートされている場合、DLL インジェクションはこのような状況に適したアプローチでしょうか?

4

7 に答える 7

4

いいえ。関数は実行可能ファイルにコンパイルされ、そのアドレスはプログラムの存続期間を通じて固定されます。

最も近いのは仮想関数です。あなたが達成しようとしていることの例を教えてください。もっと良い方法があると約束します。

于 2010-03-02T22:08:47.377 に答える
1

あなたが説明した方法でそれを行うことはできません。静的にバインドされた呼び出しのターゲットを変更する唯一の方法は、プログラムの実際の実行可能コードを変更することです。C++ 言語には、それを実現できる機能はありません。

実行時に関数呼び出しを解決したい場合は、明示的な間接呼び出し (関数ポインターを介した呼び出し) を使用するか、実行時の呼び出し解決に基づく言語機能 (仮想関数など) を使用するか、次のいずれかを使用する必要があります。古き良きiforを使った単純な分岐switch。あなたのケースでどちらがより適切かは、特定の問題によって異なります。

于 2010-03-02T22:08:40.790 に答える
1

技術的には、型の vtable を変更することで仮想関数が可能になる可能性がありますが、標準に違反する (未定義の動作を引き起こす) ことなくそれを行うことはほとんど不可能であり、特定のコンパイラが vtable を処理する方法についての知識が必要です。

他の関数については、関数のアドレスがプログラムコードに直接書き込まれるため、通常は読み取り専用メモリ領域にあるため、これは不可能です。

于 2010-03-02T22:09:19.103 に答える
0

必要なのは関数へのポインターです。同じ署名を持っていると仮定して、FuncAまたはFuncBを指すことができます。

于 2010-03-03T00:47:45.853 に答える
0

それは簡単です!

為に

実行時に funcA() を呼び出すと、実際には funcB() が呼び出されます。

次のように書きfuncA()ます。

int funcA( int a, int b) {
  return funcB( a, b );
}

:-)

于 2010-03-03T06:02:37.980 に答える
0

やりたいことを直接することはできません。ただし、既によく知っている関数ポインターを使用して、わずかに異なる基準で同様の結果を得ることができます。検討:

// This type could be whatever you need, including a member function pointer type.
typedef void (*FunctionPointer)();

struct T {
   FunctionPointer Function;
};

Functionこれで、特定のインスタンスにメンバーを設定してT呼び出すことができます。これは合理的に得ることができる限り近いものであり、関数ポインターを既に認識しているため、このソリューションを既に認識していると思います。

解決しようとしている問題のより完全な説明で質問を編集してみませんか? このままでは、何か恐ろしいことをしようとしているように聞こえます。

于 2010-03-03T01:02:45.340 に答える
0

これは純粋な C++ では不可能であると確信しています。C++ は動的言語ではありません。

于 2010-03-02T22:07:34.973 に答える