0

次のチュートリアルに従って、静的ライブラリを作成しました。

http://tldp.org/HOWTO/Program-Library-HOWTO/static-libraries.html

http://www.adp-gmbh.ch/cpp/gcc/create_lib.html

http://www.cs.dartmouth.edu/~campbell/cs50/buildlib.html

arツールを使用して C でスタティック ライブラリを生成しました。ライブラリは別のディレクトリにあります。ライブラリを適切に生成しており、それを使用して次のようにプログラムをコンパイルしています。

gcc -lpthreads main.c -o server -L thread-pool -lthreadpool

を含む現在のディレクトリの下のライブラリが呼び出さthread-poolれますlibthreadpool.a

チュートリアルによると、次のように自分の.hファイルをmain.c:に含める必要があります#include "threadpool.h"。GCC がthreadpool.h見つからないというエラーをスローしています。別のディレクトリにあるため、これは明らかです。

私が含めたときは as:#include threadpool/threadpool.h"コンパイルされますが、実際には機能しません。まだ機能を認識していません。なぜこれが起こっているのかわかりません。.h静的ライブラリをコンパイルするとき、実際にファイルやソースを実際に送信する必要はないと思いました。

ここでの問題は何ですか?どうすればこれを克服できますか?

編集:

.h ファイルが静的ライブラリと同じではないことはわかっています。私が上で述べたことが、私が両方の間で混乱しているように見える理由がわかりません.

とにかく、静的ライブラリを使用する場合、静的ライブラリで.hプログラムをコンパイルするだけでなく、ファイルもソースに含める必要があるということですか?

4

2 に答える 2

4

ライブラリとヘッダーは (関連はあるものの) 2 つの異なるものです。コンパイラのオプションを使用して問題を解決し、コンパイラにヘッダーを探すための追加のディレクトリを与えることもできます。

gcc -lpthreads -I threadpool main.c -o server -L thread-pool -lthreadpool

あなたのthreadpoolライブラリは に依存している可能性が高いため、リンクの問題を回避するためにlibpthreadコンパイラ コマンド ラインを変更する必要がある場合があります。libpthreadslibthreadpool

gcc -I threadpool main.c -o server -L thread-pool -lthreadpool -lpthreads

実際には、推奨されるオプションは-pthread、pthread ライブラリが適切にリンクされ、スレッドのサポートに必要な他のコンパイラ構成が行われるようにするオプションを使用することです (-pthreadオプションの順序は重要ではないようです)。

gcc -pthread -I threadpool main.c -o server -L thread-pool -lthreadpool

-lxyzまた、オブジェクト ファイルの前ではなく、オブジェクト ファイルの後にライブラリ (たとえば ) をリストすることをお勧めします。一部のシステムでは、両方の方法で機能します。すべての既知のシステムで、オブジェクト ファイルの後にライブラリをリストすることは常に機能します。

于 2012-12-02T01:58:54.310 に答える
2

Michael Burrが言ったように、.hファイルの#includeと、ライブラリファイルとのリンクは、2つの異なる(しかし関連する)ものです。

複数の.cソースファイルやライブラリなど、複数の部分で構成されるCプログラムを作成する場合、プロセスは2つのステップで実行されます。最初に、個々のソース.cファイルがコンパイルされます。つまり、Cソースから実行可能なマシン命令のモジュールに変換されます。次に、プログラムに必要なすべてのモジュールとライブラリがリンクされ、実行可能ファイルが作成されます。

静的リンクと動的リンクの違いは、リンクが実行されたときだけです。概念的には同じですが、静的リンク(静的ライブラリを使用)は事前に実行され、後で実行できる実行可能ファイルを形成し、動的リンクは実行直前に実行されます。

リンクのタイプ(静的または動的)は、コンパイルステップにはまったく影響しません。

個々のソースファイルのコンパイル中に、コンパイラはライブラリ関数を呼び出すためのコードを生成する必要があります。たとえば、ライブラリに引数としてdoubleをとる関数fが含まれ、ソースファイルにコードf(7)が含まれている場合、コンパイラはfという関数があり、引数としてdoubleを予期していることを知る必要があります。 、したがって、コンパイラは、関数fを実際に呼び出す前に、整数7をdoubleに変換するコードを生成できます。

これは、関数宣言を.hファイルに入れて、.cソースファイルにインクルードすることで実行されます。たとえば、その宣言は次のようになります。

void f(double);

これにより、コンパイラは正しいコードを生成できるようになり、問題が発生した場合に正しい警告とエラーメッセージを表示できるようになります。

一方、ライブラリには、コンパイルされた関数定義が含まれています。これは、何かを実行する関数の実際のコードです。

コンパイル手順はライブラリファイルとはほとんど関係がなく、静的リンクと動的リンクの違いとは関係がないことに注意してください。.hファイルを#includeできるようにするには、コンパイラーは.hファイルの場所を知る必要があります。これは、実際のライブラリファイルとはまったく異なる場所にある可能性があります。ライブラリファイルは、同じコンピューター上に存在する必要はなく、まったく存在する必要もありません。#includeを実行すると、ライブラリ内の実際の関数がまだ書き込まれていない可能性があります。

混乱の原因の1つは、gccコマンドが

gcc -lpthreads main.c -o server -L thread-pool -lthreadpool

コンパイルとリンクの両方を実行しているように見えます。ありますが、これは便宜上のことであり、舞台裏では2つの別々のステップで実行されます。

于 2012-12-02T02:26:33.730 に答える