質問

コンパイルがどのように機能するかを説明できる人はいますか?

コンパイルがどのように機能するのか理解できないようです。

より具体的に言うと、次の例があります。MSVC++ 6 で Lua 状態をロードするコードを記述しようとしています。

私はすでに次のことを行っています:

  • ライブラリの追加ディレクトリを設定し、ファイルを適切なディレクトリにインクルードします
  • extern "C" を使用 (Lua は C のみであるため、またはそう聞いた)
  • 適切なヘッダー ファイルをインクルードしました

しかし、MSVC++6 では未解決の外部シンボル (使用した Lua 関数用) に関するエラーがまだ発生します。

この問題を解決して先に進む方法を知りたいのと同じくらい、関係する基礎的なプロセスを理解できた方がずっと良いと思うので、誰かこれについての良い説明を書いてくれませんか?私が知りたいのはそのプロセスです。次のようになります。

ステップ1:

  • 入力:ソースコード
  • プロセス:解析 (おそらくここにさらに詳細を追加します)
  • 出力:ここに出力されるものは何でも..

ステップ2:

  • 入力:ステップ 1 で出力されたものに加えて、おそらく他に必要なもの (ライブラリ?)DLL?。それで?.lib?)
  • プロセス:入力で何をしたとしても
  • 出力:出力されたものは何でも

等々..

ありがとう..

おそらくこれは、シンボルとは何か、「リンク」とは正確には何なのか、「オブジェクト」コードとは何か、などを説明するでしょう。

ありがとう..こんな初心者でごめんなさい..

追伸これは言語固有である必要はありません。ただし、自分が最も使いやすい言語で自由に表現してください。:)

編集:とにかく、エラーは解決できましたが、手動で .lib ファイルをプロジェクトに追加する必要があることがわかりました。IDE 設定またはプロジェクト設定でライブラリ ディレクトリ (.lib が存在する場所) を指定するだけでは機能しません。

ただし、以下の回答は、プロセスをよりよく理解するのに多少役立ちました。どうもありがとう!..まだ詳細なガイドを書きたい人がいたら、ぜひ書いてください。:)

編集:追加の参考のために、これを非常によく説明しているある著者 (Mike Diehl) による 2 つの記事を見つけました。:)コンパイルプロセスを調べる:パート1 コンパイルプロセスを調べる:パート2

役に立ちましたか?

解決

IDEは、おそらく単一のプロセスとしてこれを提示しているが、

ソースから実行まで、一般的にCおよび関連する言語のための2つの段階のプロセスである。

1 /あなたは、あなたのソースをコーディングし、コンパイラを介して実行します。この段階では、コンパイラは、ソースとあなたが(下記参照)とリンクしようとしている他のもののヘッダファイルが必要です。

コンパイルは、オブジェクト・ファイルにソースファイルを回すから構成されます。オブジェクトファイルは、彼らが必要とする他のどのようなものを知っているあなたのコンパイルされたコードと十分な情報を持っていますが、のないのところ、他のもの(例えば、LUAライブラリ)を見つけるために。

2 /リンク、次の段階は、実行可能ファイルを作成するためのライブラリで、すべてのオブジェクトファイルを結合しています。それはほとんど利益との説明が複雑になりますので、私はここで動的リンクをカバーしています。

は、リンカが他のコードを見つけることができるディレクトリを指定する必要がありますだけでなく、あなたはそのコードを含む実際のライブラリを指定する必要があります。あなたは未解決の外部を取得しているという事実は、あなたがこれを行っていないことを示しています。

の例として、以下の簡略化されたCコード(xx.c)、コマンドを検討します。

#include <bob.h>
int x = bob_fn(7);

cc -c -o xx.obj xx.c

このはxx.cxx.objファイルをコンパイルします。コンパイルが成功するようにbob.hbob_fn()のプロトタイプが含まれています。 -cは、オブジェクトファイルではなく、実行可能ファイルを生成するようにコンパイラーに指示し-o xx.objは、出力ファイル名を設定します。

リンクに、あなたのような何かを必要とするので、

しかしbob_fn()の実際ののコードの、ヘッダファイルではなく/bob/libs/libbob.soではありません。

cc -o xx.exe xx.obj -L/bob/libs;/usr/lib -lbob

これはフォームxx.exe(LIBとの.so通常リンカーによって追加される)の(所与のパスで検索)ライブラリを使用して、xx.objからlibbob.soを作成します。この例では、-Lは、ライブラリの検索パスを設定します。 -lは、必要に応じて実行可能に含めるため見つけるために、ライブラリを指定します。リンカは、通常、「ボブ」をとり、-Lで指定された検索パスの最初の関連するライブラリファイルを見つけます。

ライブラリファイルは実際にオブジェクトファイルのコレクション(zipファイルには、複数の他のファイルが含まれているかのようなものが、必ずしも圧縮されていない)である - 未定義の外部の最初の関連発生が発見された場合、オブジェクトファイルはからコピーされますちょうどあなたのxx.objファイルのような実行可能ファイルに追加ライブラリと。これ以上の未解決の外部がなくなるまでこれは、一般的に続きます。 「関連」ライブラリが「ボブ」のテキストの変形例であり、それはそうでlibbob.alibbob.dlllibbob.sobob.abob.dllbob.soとを探すことができます。関連性は、リンカー自体によって決定され、文書化されなければならない。

それが動作するリンカーに依存しますが、これは基本的にどのようにます。

1 /オブジェクトファイルのすべてのは、彼らが解決されている必要があり未解決の外部のリストが含まれています。リンカは、これらすべてのオブジェクトを一緒に入れて、それらの間のリンクを修正(できるだけ多くの外観を解決します)。

2 /続いて、のまだの未解決のすべての外部のために、リンカは、リンクを満たすことができるオブジェクト・ファイルを探しているライブラリファイルを櫛。それはそれを見つけた場合、それはそれを引っ張る - 。オブジェクトが満たされる必要がある外観の独自のリストを持っていることで引っ張って、これはさらに未解決の外部につながることがあります。

3 /手順2を繰り返していない多くの未解決の外部またはライブラリのリストからそれらを解決する可能性のない(あなたがLUAライブラリファイルが含まれていなかったので、あなたの開発は、であったところ、これがある)。があるまで、

私は前述した合併症は動的リンクです。あなたはルーチンのスタブ(マーカーの一種)のではなく、後リットルで解決される実際のルーチンをリンクところです(実行可能ファイルを実行する)OAD時間。彼らは新しい実行ファイルにオブジェクトを再リンクすることなく変更することができるように、このようなWindowsのコモンコントロールとして物事はこれらのDLLにあります。

他のヒント

ステップ 1 - コンパイラ:

  • 入力:ソースコードファイル
  • プロセス:ソースコードを解析してマシンコードに変換する
  • 出力:オブジェクト ファイル。次のもので構成されます。
    • このオブジェクトで定義され、このオブジェクト ファイルが「エクスポート」するシンボルの名前
    • このオブジェクト ファイルで定義されている各シンボルに関連付けられたマシン コード
    • このオブジェクト ファイルには定義されていないが、このオブジェクト ファイル内のソフトウェアが依存し、その後リンクする必要があるシンボルの名前。このオブジェクトファイルが「インポート」する名前

ステップ 2 - リンク:

  • 入力:
    • ステップ 1 のオブジェクト ファイル
    • 他のオブジェクトのライブラリ (例:O/S およびその他のソフトウェアから)
  • プロセス:
    • リンクしたいオブジェクトごとに
    • このオブジェクトがインポートするシンボルのリストを取得します
    • 他のライブラリでこれらのシンボルを検索する
    • 対応するライブラリをオブジェクト ファイルにリンクします
  • 出力:単一の実行可能ファイル。これには、すべてのオブジェクトのマシン コードと、オブジェクトにインポート (リンク) されたライブラリのオブジェクトが含まれます。

2つの主な手順は、コンパイルとリンクされます。

コンパイルは、1つのコンパイル単位を(それらは単に彼らは含ますべてのヘッダーとソースファイルです)かかり、およびオブジェクト・ファイルを作成します。さて、これらのオブジェクト・ファイルでは、特定の場所(住所)で定義された関数(および静的データなどの他のもの)がたくさんあります。次のステップでは、リンク、これらの機能に関する追加情報のビットも必要とされている:自分の名前を。したがって、これらも保存されます。単一のオブジェクトファイルは、関数を参照することができます(それがコードにするときにそれらを呼び出すことを望んでいるので、実行された)他のオブジェクトファイルに実際にあることが、我々は唯一のシンボリック参照(自分の名前 ')に、ここでは単一のオブジェクトファイルを扱っているので、これらの他の機能は、オブジェクト・ファイルに格納されます。

次は、リンクくる(のは、ここで静的リンクして自分自身を制限してみましょう)。 (直接、または、彼らはの.libファイルに一緒に投げてきた後の)最初のステップで作成されたオブジェクトファイルが一緒になっていると、実行ファイルが作成される場所のリンクがあります。 リンクのステップでは、別のオブジェクトファイルまたはLIBのすべてのそれらのシンボリック参照は、正しいオブジェクト内の名前を検索する関数のアドレスを見つけ、右のアドレスを入れて、(彼らがすることができた場合)に解決されています場所ます。

さて、「にextern 『C』」あなたが必要なものについて何かを説明します

Cは、関数のオーバーロードはありません。関数は常に名前で認識可能です。あなたはCコードとしてコードをコンパイルするときにそのため、機能の唯一の本当の名前は、オブジェクトファイルに格納されます。

C ++は、しかし、 '関数/メソッドのオーバーロード' と呼ばれるものがあります。これは、関数の名前は、もはやそれを識別するのに十分であることを意味しません。 C ++コンパイラは、したがって、関数のプロトタイプを含む関数の「名前」(名前プラスプロトタイプが一意の機能を同定するため)を作成します。これは、「名前の符号化」として知られています。

あなたがC ++プロジェクトから(例えば、コンパイル済みのLuaのバイナリ)「C」コードとしてコンパイルされたライブラリを使用する場合、

「のextern 『C』」仕様が必要とされます。

あなたの正確な問題のために:それはまだ動作しない場合は、これらのヒントは、役立つかもしれません。 * LuaのバイナリはVC ++の同じバージョンでコンパイルされていますか? *単にあなたのVCソリューション内、またはC ++コードのような別のプロジェクトとしてのいずれかで、Luaのを自分でコンパイルすることができますか? *あなたは正しいですか?

すべて「のextern 『C』」ものを持っていることを確認しています

あなたはプロジェクトの設定に移動して、あなたが持っている場所のディレクトリを追加する必要があり、そのどこかに「リンカ」タブのLUAライブラリ* .libファイル。申し訳ありませんが、私はそれを見ることができない、または何か「ライブラリを含む」という設定ます。

C ++でコンパイルは2つの段階で動作するため、

あなたは「未解決の外部シンボル」を得る理由があります。まず、コードは、それ自身の.objファイル内の各.cppファイルをコンパイルしますし、「リンカー」が起動し、.exeファイルにファイルを.OBJそのすべてに参加します。 .libファイルが.OBJファイルのちょうど束は、ライブラリの配布少しのsimplierを作るために一緒にマージされています。 だから、すべて「の#include」とextern宣言を追加することによって、あなたはそれがわからないので、そのコードを見つけることができないこれらの署名が、リンカーを有するコードを見つけることが可能だろうどこかでそのコンパイラを告げたところ、実際のコードでこれらの.libファイル配置されます。

あなたはライブラリのREDMEを読んだことを確認し、通常、彼らはあなたのコードでそれを含めるようにしなければならなかったものの、むしろ詳細な説明を持っています。

また、これをチェックすることをお勧めします:コンパイラ、アセンブラ、リンカおよびLoader:BRIEF STORY 。

scroll top