4

私はライブラリの操作にかなり慣れておらず、静的ライブラリとオブジェクトファイルに関するいくつかの詳細を理解しようとしているところです。

概要

私が気付いている動作は、複数のオブジェクトをリンクして実行可能ファイルを問題なく作成できることですが、それらのオブジェクトを静的ライブラリに結合する中間ステップを実行すると、それらの静的ライブラリをリンクして実行可能ファイルを作成するには、 linkコマンドにCランタイムライブラリが必要です。

また、レコードとして、コマンドラインからVisualStudio2010でコンパイル/リンクを行っています。私がフォローしているプロセスの詳細は以下のとおりです。



まず、プロジェクトに4つのソースファイルがあると しましょう:main.c、、、、。 util1.cutil2.cutil3.c

何が機能するか

  1. 次のコマンドを使用して、これらのソースをコンパイルできます。その結果、、、、、および

    cl -c main.c util1.c util2.c util3.c

    の4つのオブジェクトファイルが作成さmain.objれましutil1.objた。これらのオブジェクトファイルにはそれぞれ、リンク時にこれらのオブジェクトファイル内の未解決の外部依存関係がないか静的Cランタイムライブラリlibcmt.libを追加でチェックする必要があることをリンカに通知することを目的としたDEFAULTLIBステートメントが含まれています。util2.objutil3.obj

  2. これらのオブジェクトを次のコマンドでリンクすることにより、「app_objs.exe」という名前の実行可能ファイルを作成できます。

    link -out:app_objs.exe main.obj util1.obj util2.obj util3.obj

    手順1で説明したように、デフォルトのライブラリステートメントをオブジェクトに追加するコンパイラの手順により、リンカーはランタイムライブラリを使用しました。

私が混乱しているところ

  1. これらのオブジェクトを静的ライブラリに結合し、結果のLIBファイルをリンクして実行可能ファイルを作成するという中間ステップが必要だとします。まず、次のコマンドを使用してこれらのライブラリを作成できます。

    link -lib -out:main.lib main.obj
    link -lib -out:util.lib util1.obj util2.obj util3.obj

  2. さて、私の当初の考えは、これらのライブラリをリンクするだけで、「何が機能するか」のステップ2で作成したものと同じ実行可能ファイルを使用できるというものでした。次のコマンドを試したところ、エントリポイントを指定する必要があることを示すリンカーエラーLNK1561が表示されました。

    link -out:app_libs.exe main.lib util.lib

  3. Microsoftのドキュメントから、オブジェクトファイルなしでライブラリをリンクするには、エントリポイントを指定する必要があることが明らかであるため、サブシステムを「コンソール」として設定するようにコマンドを変更して、実行可能ファイルがコンソールアプリケーションであることを指定しました(特定のエントリポイントを暗示し、それによってそのエラーを解決します):

    link -out:app_libs.exe -subsystem:console main.lib util.lib

    残念ながら、mainCRTStartupが未解決の外部シンボルであることを示すリンカーエラーが発生します。これはCランタイムライブラリで定義されていることを理解しているので、libcmt.libに対してリンクすることを手動で指定することでこの問題を解決できます。これにより、機能する実行可能ファイルが得られます。

    link -out:app_libs.exe -subsystem:console main.lib util.lib libcmt.lib

私が理解していないのは、コンパイラが各オブジェクトファイルに配置したデフォルトのライブラリ情報を使用してlibcmt.libへの依存関係を解決できなかった理由です。libcmt.libが必要であると明示的に指定せずにオブジェクトファイルをリンクでき、オブジェクトファイルのコンテナである静的ライブラリを作成した場合、libcmt.libが必要であると明示的に指定せずに、これらの静的ライブラリをリンクできないのはなぜですか?これはまさにその通りですか、それともリンカーがランタイムライブラリ内の未解決のシンボルをチェックすることを認識できるように静的ライブラリを作成する方法はありますか?



ご協力いただきありがとうございます。私がここで根本的に間違った考えを持っているなら、私はこれらすべてを正しく学ぶための良い参考文献に関する提案が欲しいです。

4

1 に答える 1

1

あなたの誤解に対する答えは、.lib ファイルはしばしばそれ自体が製品であり、コンパイラはそれらの仮定を安全に行うことができないということです。それが「外部」の目的です。

ユーザーが完全に無力であり、静的リンケージを望んでいる/必要としているために誰かのプラットフォーム用のバイナリを作成する場合、特定のランタイムエントリポイントに結び付けずに foo.h と libfoo.lib を提供する必要があります。彼らは、DLL であれ EXE であれ、最終製品のためにすでに独自のエントリ ポイントを定義している可能性があります。

ランタイムが必要な場合もあれば、エントリ ポイントを含む独自の .obj が必要な場合もあります。mainCRTStartup を独自に宣言および定義すると、ターゲット プラットフォームの重要な命令を実行していない可能性があることに注意してください。

于 2013-05-09T13:46:14.773 に答える