2009-12-08 2 views
7

がOK、DLLとして地元のvftable問題をEXEをロードするので、この1つは私と一緒にとても裸説明するのabitは長い..ですC++:私は通常のスタンドとして使用されているTEST.EXEという名前のexeファイルを持っている

単独アプリケーションです。このexeを別のアプリケーションapp.exeの中のモジュール(dll)として使いたいです。

someMethod()が仮想で、MyClassのは、仮想D'のTORを持って
void doTest() 
{ 
    MyClass *inst = new MyClass(); 
    inst->someMethod(); 
} 

TEST.EXEのコードは本当に簡単なものなどを行います。
doTest()がtest.exeからエクスポートされ、test.libというlibが作成されます。
app.exeはこのlibにリンクされ、起動時にtest.exeを静的にロードします。

私はtest.exeをスタンドアロンで実行しているとうまく動作しますが、実行しているときにapp.exeからロードされると、クラッシュします。
デバッガでコードをステップ実行すると、クラッシュが仮想メソッドの呼び出しにあることが明らかになりました。 vftableがどうにかして悪くなることが判明しました。

MyClassのコンストラクタ内のコードが実行されているときにvftableが1つですが、newが呼び出されると "local vftable"と呼ばれるものが置き換えられます。私はthis obscure discussion about why this isを見つけました。

デバッグの1日後、test.exeがスタンドアロンで、モジュールとしてロードされているときに、この "local vftable"内のポインタが同じであることが私に発生しました。これは正しいとは言えません...
この理論をテストするために、リンカーオプションの読み込みアドレスを、app.exeにあるときにtest.exeがロードされているアドレスに変更しました今、全部うまくいく。

明らかに、これは永久的な解決策ではありません。次回このランダムに選択されたアドレスが占有され、同じ問題が再び発生する可能性があるからです。

私の質問:なぜこの "ローカルvftable"は、exeの静的な読み込みアドレスに結びついていますか? exeモジュールを悪いものとしてロードしていますか?なぜそれは静的アドレスにロードされていると仮定しますか?

文脈だけ:これはすべてMSVC 2008、Windows XP x64で行われます。

答えて

3

私は、単にコンパイル設定を追加して、実際のdllとしてexeファイルをコンパイルするのではなく、1つのように動作させることです。

/fixed:noを使用すると、何らかの理由で問題が解決されませんでした。

exesとDLLの別の違いは、エントリポイントが異なることです。 DLLのエントリポイントはDllMainであり、exeとして、main()またはWinMain()を最終的に呼び出すCRTにエントリポイントがあります。

4

VC++は通常、リロケータブルである必要がないため、デフォルトで.exesからリロケーション情報を取り除きます。

強制的に再配置情報を/ fixed:noで保持することができます。参照してください:http://msdn.microsoft.com/en-us/library/w368ysh2.aspx

+2

私はそれを試みましたが、何らかの理由で何の効果もないようです – shoosh

関連する問題