問題タブ [vtable]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 複数の仮想継承と型キャストのための仮想テーブルと仮想ポインタ
vptr とメモリ内のオブジェクトの表現について少し混乱しています。問題をよりよく理解するのに役立つことを願っています。
B
inherits fromA
と、両方が virtual functions を定義することを検討してくださいf()
。私が学んだことから、メモリ内のクラス B のオブジェクトの表現は次のように[ vptr | A | B ]
なります。また、オブジェクトをからにキャストしても、オブジェクトの最後の部分を無視する以外は何もしないことも理解しました。本当ですか?この振る舞いは間違っていませんか?型のオブジェクトがではなく メソッドを実行するようにします。vtbl
vptr
B::f()
B
A
B
A
A::f()
B::f()
クラスの数
vtables
としてシステムにいくつかありますか?vtable
2 つ以上のクラスを継承する of クラスはどのようになりますか? C のオブジェクトはメモリ上でどのように表現されるでしょうか?質問 3 と同じですが、仮想継承があります。
com - x86アセンブリでのCOMオブジェクトvtableの構築
NASMを使用してx86アセンブリでCOMオブジェクトを構築しています。私はCOMを非常によく理解しており、x86アセンブリをかなりよく理解していますが、2つをメッシュ化すると、ハングアップします...(ちなみに、x86アセンブリの使用を思いとどまらせることを考えている場合は、ご遠慮ください。これをx86アセンブリで構築するのには特別な理由があります!)
COMオブジェクトで使用するvtableを作成しようとしていますが、関数への実際のポインターではなく、奇妙なポインターを取得し続けています。(相対的なオフセットを取得しているか、NASMが一時的な値をそこに埋め込んでおり、リンク中に実際の値に置き換えられていないと考えています)
私が構築しようとしている現在のインターフェースは、IClassFactory
次のようなコードのインターフェースです。
注:これはすべてのコードではありません。別のファイルにDllGetClassObject、DllMainなどがあります。
しかし、(NASM:を使用して)アセンブルして(nasm -f win32 comobject.asm
MS Link:を使用して)リンクlink /dll /subsystem:windows /out:comobject.dll comobject.obj
し、OllyDbgを使用して実行可能ファイルを調べると、vtableに奇妙な値が表示されます。たとえば、前回のビルドでは、関数の実際のアドレスは次のとおりです。
- QueryInterface-0x00381012
- AddRef-0x0038101A
- リリース-0x00381020
- CreateInstance-0x00381026
- LockServer-0x0038102E
しかし、vtableは次の値で出てきました:
- QueryInterface-0x00F51012
- AddRef-0x00F5101A
- リリース-0x00F51020
- CreateInstance-0x00F51026
- LockServer-0x00F5102E
これらの値はひどく疑わしいように見えます...ほとんど移転が行われなかったように。また、vtableは0x00F5104Aとして出力され、これらはすべてアクセスできないメモリアドレスです。(情報提供の目的で、これらの値は毎回異なります)
Visual Studio 2010Expressを使用してC++で同じことを試してみましたが、すべてうまくいきました。だから私はそれが私のアセンブリに欠けているものだと思います...
これらの値が適切に出力されない理由を誰かが私に指摘できますか?
c++ - クラスのオブジェクト(単一/多重継承を使用)にはいくつのvptrがありますか?
clas(child)がbase1とbase2を複数継承する基本クラスを持つ単一の継承を持つオブジェクトに通常必要なvptrの数。オブジェクトが単一の継承と多重継承のカップルを持っている場合に、オブジェクトが提供したvptrの数を識別するための戦略は何ですか。標準ではvptrsについて指定されていませんが、実装が仮想関数の実装をどのように行うかを知りたいだけです。
c++ - DLL によってエクスポートされたクラスの不適切な vtable レイアウト: ヘッダーと vtable の構築に関する明確化の要求
当面の問題は解決されましたが、クラスの vtable を構築するためにどのデータが使用され、vtable のレイアウトがどこに保存されるかについて、少し混乱しています。誰かが説明を提供してくれたり、私の好奇心を満たしてくれる情報を教えてくれたりできれば、とてもありがたいです。
バックグラウンド
- 2 つの個別の VC6.0 プロジェクト: 1 つは exe 用、もう 1 つは dll 用です。
- アプリケーションには、dll プロジェクト リリースの .lib、.dll、および .h ファイルが含まれています。
- 新しいリリースの準備が整うと、.lib、.dll、および .h ファイルがdll プロジェクトから exe プロジェクトにコピーされます。
- この仕組みを受け継いでいます。
問題:
最近、DLL に変更を加え、.lib と .dll をコピーしましたが、ヘッダー ファイルをコピーするのを忘れていました。いくつかの階層の変更があり、その結果、1 つの特定のクラス ( と呼びますInternalClass
) の vtable が変更されました。
exe は のメソッドを直接呼び出しませんInternalClass
。代わりに、オブジェクトInterfaceClass
へのポインターをカプセル化し、そのポインターに対してさまざまなメソッドを呼び出す別のクラスのインスタンスを作成します (それを呼び出します) 。InternalClass
実行時に、メソッド内からInterfaceClass
メソッドへInternalClass
の呼び出しが、実際には間違ったメソッドを呼び出していました(つまり、InterfaceClass
呼び出しInternalClass::A
てInternalClass::B
実際に実行されていました)。asmを見ると、フィックスアップまたはサンク (専門用語が間違っていたらすみません!) がvtable への正しいオフセットを使用していたことがわかります。ただし、vtable 自体には、古いヘッダー ファイルから期待されるポインタのリストが含まれていました。
実際の質問:
私は自分の間違いに気づき、ヘッダー ファイルをコピーして再コンパイルしましたが、すべて問題ありませんでした。ただし、1 つのしつこい質問が残っています。
vtables のレイアウトはいつ決定され、実行時にこれらのクラスの vtable を構築するためにどのような情報が使用されますか? つまり、dll がコンパイルされたときに適切なvtable がアセンブルされている必要があり、オフセットなどを からInterfaceClass
への呼び出しに使用できるように思われInternalClass
ます。では、なぜ実行時に古い vtable が使用されたのでしょうか? exeが持っているヘッダーを使用してコンパイルされたときに、レイアウトも個別に決定されますか?
これがまったく明確かどうかはわかりません。私が求めていることが複雑すぎる場合はお知らせください。ありがとう!
c++ - 仮想関数オブジェクトのスライス
私の質問は、基本クラスの仮想関数を呼び出すオブジェクトスライスの場合に仮想関数がどのように機能するかを説明するこの質問と、以下のコードの派生クラスの仮想テーブルレイアウトを説明するウィキペディアの記事を参照したものです。
上記のプログラムは "In A::func" を出力します。
しかし、クラス B の仮想テーブルが基本クラス A::func を認識していない場合、どうすれば A::func を呼び出すことになりますか?
c++ - C++のvtableとは何ですか
重複の可能性:
なぜ仮想テーブルが必要なのですか?
C ++のvtableとは何ですか?
これまでのところ、vtableは仮想関数へのポインターの配列を持つ仮想テーブルであることを知っています。実際の実装例で読める記事はありますか?(どんなウォークスルーでもありがたいです。)
c# - vtablesはc++とc#でどのように実装されていますか?
この状況を考えてみましょう(c ++では、c#クラスではA、Bはインターフェイスです):
C#コンパイラは常に1つのvtableを作成しますか?キャスト時にポインタを修正しますか?
c++ - C++ v-table: 言語またはコンパイラ依存の一部?
v-table (仮想メソッド テーブル) は C++ 仕様の一部ですか、それとも仮想メソッド ルックアップを解決するのはコンパイラ次第ですか?
仕様の一部である場合: なぜですか?
コンパイラに依存していると思いますが、仕様の一部だと誰かが私に言いました。
参考文献大歓迎です!
c++ - COM オブジェクト関数の API フック?
StackOverflowians の皆さん、こんにちは。
ここで発見されたように、Windows 7 には、Windows Explorer インスタンスに対して DISPID_BEFORENAVIGATE2 イベントが発生しないというバグがあります。このイベントにより、ナビゲーションが行われようとしているときにシェル拡張に通知でき、(私にとって最も重要なことに) ナビゲーションをキャンセルする機会があります。私はかなり長い間回避策を探していましたが、見つけたと思います。ただ、安全性については意見を頂きたいです。
私は最近 API フックで遊んでおり、拡張機能のいくつかの関数をフックするために既に使用しています。ナビゲーションを制御する関数が IShellBrowserにあることに気付きました。最初はそのようなものをフックすることはできないと思っていましたが、COM オブジェクトのレイアウトについて読んだときに、アクティブなインスタンスの vtable から適切な関数ポインターを取得するだけで可能であることに気付きました。案の定、それは夢のように機能します。フックが設定されると、すべての Explorer ウィンドウのすべてのナビゲーションが迂回機能を介して実行され、ターゲット pidl に基づいてそれらを拒否するかどうかを決定できます。
だから私の質問は、これをしてはいけない理由はありますか? COM オブジェクト関数をフックするために使用される API フックについては聞いたことがありません。それが機能しない状況はありますか?それは危険ですか?(少なくとも、通常の API フック以上のもの)
関連するコードは次のとおりです。私はMinHookを使用しています。これは、トランポリン関数の実証済みの方法を使用する最小限のフック ライブラリです。
c++ - 別の親の関数を使用して、基本クラスが親の純粋仮想関数の定義を満たすにはどうすればよいですか
既存の C++ プロジェクトを拡張しています。2 つの親クラスから派生した基本クラスがあります。親の 1 つに純粋な仮想機能があります。その純粋仮想関数を、もう一方の親に実装された関数によって定義したいと考えています。
したがって、親の純粋仮想関数を定義する基本クラスの義務を別の親が満たしてほしいと思います。私は 2 つのアプローチを試しましたが、どちらもコンパイラ エラーにつながりました。
何か案は?
これは、私の最初のアイデアを示す C++ プログラムです。コンパイラがbase2
の の定義を使用することを期待していvfunc()
ます。
derived
コンパイラは、これがまだ抽象クラスであると報告します。
これが私の2回目の試みです:
私は実際にこれでうまくいくと思っていましたが、代わりにリンカが私が理解できない一連の vtable エラーを出しています: ( Mac OS 10.6, gcc 4.2.1 )