CまたはC ++で外部関数をソース/リンクするにはどうすればよいですか?
-
03-07-2019 - |
質問
編集:重要な場合に備えて、明確にする必要があると思います。 AIX Unixボックスを使用しているため、VACコンパイラを使用しています-gnuコンパイラは使用していません。 編集の終了
C / C ++ではかなりさびているので、これが簡単な質問である場合はご容赦ください。
いくつかのCプログラムから共通の関数を取り出して、共有ライブラリまたは共有オブジェクトに配置したいと思います。 perlでこれを行っていた場合、サブルーチンをperlモジュールに入れて、必要なときにそのモジュールを使用します。
例のために、この関数があるとしましょう:
int giveInteger()
{
return 1034;
}
明らかにこれは実世界の例ではありませんが、その機能を共有したい場合、どのように進めますか?
2つのオプションがあると確信しています:
- 共有関数をファイルに入れ、コンパイル時にメインプログラムでコンパイルします。共有機能に変更を加えた場合、メインプログラムを再コンパイルする必要があります。
- 共有関数をファイルに入れ、それを共有ライブラリとしてコンパイルし(用語が正しい場合)、メインプログラムをその共有ライブラリにリンクさせます。 (コンパイル後に)共有ライブラリに加えた変更は、メインプログラムを再コンパイルせずに、実行時にメインプログラムに統合されます。
その考えを修正しますか?
もしそうなら、どうすればそれらの方法のどちらか/両方を完了できますか?私は多くのことを検索し、自分のプログラムを他の誰かの共有ライブラリにリンクする方法を見つけたようですが、自分の共有関数を作成して自分のプログラムで使用できるようにコンパイルする方法はありません。
どうもありがとう!
ブライアン
編集:
結論
皆さん、助けてくれてありがとう!他の人が利益を得られるように、この投稿に(AIX上の動的共有ライブラリに対して)私のために働いているものを追加すると思いました:
共有関数をコンパイルします:
xlc -c sharedFunctions.c -o sharedFunctions.o
次に、共有オブジェクトにします:
xlc -qmkshrobj -qexpfile=exportlist sharedFunctions.o
xlc -G -o libsharedFunctions.so sharedFunctions.o -bE:exportlist
次に、別のプログラムにリンクします:
xlc -brtl -o mainProgram mainProgram.c -L. -lsharedFunctions
また、別のコメントがこのリンクを見つけるのを助けてくれました。 http: //publib.boulder.ibm.com/infocenter/comphelp/v7v91/topic/com.ibm.vacpp7a.doc/proguide/ref/compile_library.htm
私を助けてくれたすべての人に感謝します!
解決
ええ、あなたは正しいです。 1つ目は静的ライブラリと呼ばれ、2つ目は共有ライブラリと呼ばれます。これは、コードがコンパイル時に実行可能ファイルにバインドされていないためです。ロードされます。
静的ライブラリ
次のようにライブラリのコードをコンパイルします。
gcc -c *.c
-c
は、プログラムにオブジェクトファイルをリンクしないように指示しますが、コンパイルされた各 .c
ファイルのオブジェクトファイルのみを残します。次に、それらを1つの静的ライブラリにアーカイブします。
ar rcs libmystuff.a *.o
man ar
は、rcsオプションの意味を教えてくれます。現在、libmystuff.aは a rchiveファイルです(zipファイルビューアーで開くことができます)。これらのオブジェクトファイルには、各オブジェクトファイルのシンボルのインデックスが含まれています。プログラムにリンクできます:
gcc *.c libmystuff.a -o myprogram
これで、プログラムの準備ができました。コマンドで静的ライブラリが表示される順序が重要であることに注意してください。 リンクの注文の回答をご覧ください。
共有ライブラリ
共有ライブラリの場合、次を使用してライブラリを作成します
gcc -shared -o libmystuff.so *.c
それだけで、libmystuff.soは s 共有された o bjectファイルになりました。プログラムをリンクしたい場合は、 /etc/ld.so.conf
ファイルにリストされているディレクトリ、または- L
をGCCに切り替えるか、LD_LIBRARY_PATH変数にリストします。リンクするとき、gccに伝えるライブラリ名から lib
プレフィックスと .so
サフィックスを切り取ります。
gcc -L. -lmystuff *.c -o myprogram
内部では、gccは引数をGNUリンカーに渡すだけです。 -###
オプションを使用して、渡される引数を確認できます。Gccは、各サブプロセスに指定された正確な引数を出力します。
リンクプロセスの詳細(内部で行われる処理)については、 Linux GCCリンカー回答。
他のヒント
3番目のオプションがあります。一般に、C ++コンパイラはCルーチンをリンクできる必要があります。必要なオプションはコンパイラごとに異なる可能性がありますので、RをMにしてください。ただし、基本的には、次のようにg ++でコンパイルできるはずです。
$ g++ -o myapp myapp.cpp myfunc.c giveint.c
...または個別にコンパイル
$ gcc -c myfunc.c
$ gcc -c giveint.c
$ g++ -c myapp.cpp
$ g++ -o myapp myapp.o myfunc.o
関数の宣言も含める必要があります。 C ++で次のように実行します
extern "C" {
int myfunc(int,int);
int giveInterger(void);
}
再コンパイルと再リンクを区別する必要があります。
giveInteger()
を別の(アーカイブ)ライブラリに入れて、後で修正する場合、それが定義されているソースファイルを(明らかに)再コンパイルする必要があり、< em> relink それを使用するすべてのプログラム。ただし、このようなプログラムを再コンパイルする必要はありません[1]。
共有ライブラリの場合、ライブラリを再コンパイルおよび再リンクする必要があります。ただし、それを使用するプログラムを再リンクまたは再コンパイルする必要はありません。
AIXでのC ++共有ライブラリの構築は以前は複雑でした。 makeC ++ SharedLibシェルスクリプトを使用する必要がありました。しかし、VAC 5.0および6.0では非常に簡単になりました。あなたがする必要があるのは[2]だけだと思います:
xlC -G -o shr.o giveInteger.cc
xlC -o myapp main.cc shr.o
[1]正しいMakefileを作成する場合(推奨される方法です)、 make
と入力すると、これらすべてが自動的に行われます。
[2] AIXには、問題を複雑にする可能性のある特定の機能があります。デフォルトでは、共有ライブラリーがメモリーにロードされ、「スティック」が使用されます。その後の再起動までそこに。したがって、shr.oを再構築し、プログラムを再実行して、「古い」を観察できます。実行されているライブラリのバージョン。これを防ぐための一般的な方法は、shr.oを世界で読み取り不可能にすることです。
chmod 0750 shr.o