1

続く長い投稿でごめんなさい。

Microsoftが提供する静的リンクと動的リンクのCランタイムとC++ランタイムを混在させるのは良い考えではないことを私は知っています。残念ながら、私たちのアプリケーションはすでにそれらを混ぜ合わせており、それを修正しようとしています。さまざまな理由(MSIに慣れていないこと、MSMを十分にサポートしていない可能性のあるNSISを使用していること、時間とリソースの不足など)により、CRTを動的ではなく静的にリンクすることにしました。これが良い考えではない理由は知っていますが、今のところ私たちが選んだのです。


私たちのコードは、ほとんどが標準のC ++であり、他の多くのオープンソースライブラリによって補完されています。

アプリケーションの構造は次のとおりです。静的ライブラリを生成するさまざまなモジュールは、それ自体がリンクされてさまざまなものを作成し、その中で1つの実行可能ファイルが問題を引き起こします。

リリースでは、すべてのコードを/MTでビルドします。一部のオープンソースライブラリでは、プリコンパイルされたバイナリを使用し、一部は/ MDでプリコンパイルされたdllであったため、ランタイムが混在していました。そこで、それらを/ MTで再コンパイルし、dllではなく静的ライブラリを作成しました。この変換はライブラリごとに行われないため、/MDを使用するいくつかのdllとリンクします。


その結果、depends.exeでは、1つの実行可能ファイルを除くすべてのものがmsvcr80.dllまたはmsvcp80.dllに直接依存していません。直接依存しないということは、msvcr80.dllがdepends.exeによって示されるツリーのルートの子ではないことを意味します。ライブラリdllの1つによってプルされたmsvcr80.dllが見つかることもありますが、それはツリーのより深いレベルです。

その1つの厄介な実行可能ファイルの最初のレベルにmsvcr80.dllがある理由を知るにはどうすればよいですか?その実行可能ファイルをmsvcr80.dllに直接リンクする理由は何ですか?

1つの理由は、リンクが/MDを使用してCRTと動的にリンクするライブラリAに静的にリンクしていることである可能性があります。したがって、ライブラリAのコードは実行可能ファイルに含まれるため、実行可能ファイルはmsvcr80.dllにリンクします。しかし、どのライブラリがそれを行っているかをどのように知ることができますか?


私がこれまでに試したこと:

  • 静的にリンクされた.libファイルをdepends.exeにロードする->depends.exeは静的ライブラリではなく実行可能ファイルまたはdllを想定しているため、機能しません
  • 静的にリンクされた.libファイルでdumpbin.exe/DIRECTIVESを使用します->それらのいずれもmsvcrt80.dllを表示しませんでした(デバッグ中、すべてに/ MDdを使用しようとすると、msvcrt80d.dllが表示されたため、メソッドは良いです。静的にリンクされたすべてのオープンソースライブラリが/MTで正しくコンパイルされていることを証明します)
  • / VERBOSE:LIBリンカーフラグを使用します->実際にmsvcr80.dllのインポートライブラリであるmsvcrt.libをプルしていることを示したため、問題が発生しましたが、なぜそれが行われているのかはわかりませんでした
  • VisualStudioで/VERBOSEリンカーフラグを使用します+追加の依存関係libcmt.lib+すべてのデフォルトライブラリを無視しますYES+特定のライブラリを無視します:msvcrt.libを削除するか、誰がそれをプルするかを確認するために必死に試みます。結果は私を困惑させました:
    C:\ Program Files \ Microsoft Visual Studio 8 \ VC \ lib \ msvcrt.libの検索:  
      「public:virtual void * __thiscall type_info :: `vectordeleted destructor'(unsigned int)」(?? _ Etype_info @@ UAEPAXI @ Z)が見つかりました  
        libcmt.lib(typinfo.obj)で参照されています  
        ロードされたmsvcrt.lib(ti_inst.obj)  
            msvcrt.lib(ti_inst.obj):エラーLNK2005: "private:__thiscall type_info :: type_info(class type_info const&)"(?? 0type_info @@ AAE @ ABV0 @@ Z)はすでにlibcmt.lib(typinfo.obj)で定​​義されています)。  
            msvcrt.lib(ti_inst.obj):エラーLNK2005: "private:class type_info&__ thiscall type_info :: operator =(class type_info const&)"(?? 4type_info @@ AAAEAV0 @ ABV0 @@ Z)すでにlibcmt.libで定義されています(typinfo.obj)  
      "void __stdcall` eh vector destructor iterator'(void *、unsigned int、int、void(__thiscall *)(void *)) "(?? _ M @ YGXPAXIHP6EX0 @ Z @ Z)が見つかりました  
        msvcrt.lib(ti_inst.obj)で参照されます
        ロードされたmsvcrt.lib(ehvecdtr.obj)

私が理解している限り、libcmt.libのtypinfo.objはシンボルを参照し、msvcrt.libで検索し、ti_inst.objで見つかった後、2回定義されているというエラーをスローします。しかし、これは意味がありません。libcmt.libにすでにシンボルがある場合、なぜmsvcrt.libでそれを検索し、実行可能ファイルにmsvcr80.dllをもたらすのでしょうか。そして、より一般的には、静的ライブラリが動的インポートライブラリでシンボルを検索するのはなぜですか?Ignore固有のライブラリにmsvcrt.libがある場合、リンカがmsvcrt.libを参照するのはなぜですか?

お待ち頂きまして、ありがとうございます :-)。

4

2 に答える 2

3

私には自分の問題に対する解決策があります。おそらく古代からそこに残された愚かな間違いでした。

msvcrt.libは、[追加の依存関係]ボックスで明示的に言及されていました:-(もちろん、dllは依存関係になりました。また、すべてのオープンソースライブラリのため、このボックスには多くのテキストがあるため、気づきませんでした。そして正直なところ、私たちのプロジェクトにそのような重大な間違いがあるとは想像していなかったので、私たちはそのボックスを注意深く見ることさえ考えていませんでした。

于 2009-10-15T07:23:40.640 に答える
1

実行可能ファイルをdepends.exeで開き、dependsに組み込まれているプロファイラーを実行します。これにより、すべてのdllがロードされる理由と、それらがロードされる場所がログに記録されると思います。「LoadLibrary関数呼び出しのログ」オプションを参照してください。

于 2009-10-14T23:51:04.617 に答える