| プログラム / 2010/01/02 (Sat) / 編集 |
前準備
とりあえず「DYLD_LIBRAY_PATH」(Linuxでいうところの「LD_LIBRAY_PATH」)に「.」を追加しておく。あとはサンプルプログラムを用意しとこう!
libhello.h
void hello(void);
libhello.c
#include <stdio.h>
void hello(void) {
printf("Hello, library world.\n");
}
demo_use.c
#include "libhello.h"
int main(void) {
hello();
return 0;
}
オブジェクトファイルを生成しておく
gcc -Wall -g -c demo_use.c -o demo_use.o
demo_dynamic.c
/*
* 動的にライブラリをロードするルーチン用に dlfcn.h が必要
*/
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
/*
* "libhello.h" をインクルードする必要がないことに注意して
* ください。但し、関連情報を指定する必要があります。
* dlsym() で取得する値を保持するための型が必要です。
*/
/*
* "simple_demo_function" 型は、引数を取らず、何も値を返さない
* 関数を示しています。
*/
typedef void (*simple_demo_function)(void);
int main(void) {
const char *error;
void *module;
simple_demo_function demo_function;
/* 動的ライブラリをロードする */
module = dlopen("libhello.so", RTLD_LAZY);
if (!module) {
fprintf(stderr, "libhello.so をオープンできませんでした: %s\n", dlerror());
exit(1);
}
/* シンボルを取得する */
dlerror();
demo_function = dlsym(module, "hello");
if ((error = dlerror())) {
fprintf(stderr, "hello が見つかりませんでした: %s\n", error);
exit(1);
}
/* 動的ライブラリ内の関数を呼び出す */
(*demo_function)();
/* 全て終了。きちんとクローズする */
dlclose(module);
return 0;
}
オブジェクトファイルを生成しておく
gcc -Wall -g -c demo_dynamic.c -o demo_dynamic.o
静的ライブラリ (Static Library)
「.a」なライブラリ。各プログラムとリンクされていて、他のプログラムと共有することはできない。
普通にオブジェクトファイルを生成
gcc -Wall -g -c -o libhello.o libhello.carコマンドで静的ライブラリを生成
ar rcs libhello.a libhello.oでは、実行ファイルを生成
gcc -g -o demo_use_static demo_use.o -L. -lhello
共有ライブラリ (Shared Library)
「.dylib」(Linuxでは「.so」)なライブラリ。複数のプログラムが同時に同じライブラリを使用することができる。Linuxとかではローダブル・モジュールと一体になってるけどMac(というかDarwin)では別々。
位置独立コード (PIC: Position Independent Code) の生成のために「-fPIC」、リンカは"共通"のシンボルを共有ライブラリ内に持つことは認めないので「-fno-common」をつけてオブジェクトファイルを生成
gcc -fno-common -fPIC -Wall -g -c libhello.c共有ライブラリなので「-dynamiclib」、インストール先を明示しないといけないので「-install_name フルパス」、バージョンの指定もしとく。 ちなみに、バージョンが2.4.5の場合、2 が主リビジョン (非互換の API 変更), 4 が副リビジョン (後方互換な API の変更),5 がバグ修正(teeny)リビジョン(完全に互換性のある変更)らしい、今回の例ではバージョンは0.0.0なので、互換バージョンは「-compatibility_version 0.0」、現在バージョンは「-current_version 0.0.0」と指定する。
gcc -g -dynamiclib -install_name libhello.0.0.0.dylib -compatibility_version 0.0 -current_version 0.0.0 -o libhello.0.0.0.dylib libhello.o -lc「lc」がついているのはlibhello.cでstdio.hを使っており、libcに依存しているから。
インストールパスは「-install_name」で指定したので、ldconfigは要らない。なのでsonameもlinker nameもlnで作ります。
ln -s libhello.0.0.0.dylib libhello.0.dylib ln -s libhello.0.0.0.dylib libhello.dylibでは、実行ファイルを生成
gcc -g -o demo_use_shared demo_use.o -L. -lhello
ローダブル・モジュール (Dinamics Library)
「.so」なライブラリ、Apple的には「.bundle」とかが推奨らしい。 プログラム中で「dllfunc.h」の「dlopen」などを使って動的に読み込み&クローズできる。frameworkに使われているやつ。
位置独立コード (PIC: Position Independent Code) の生成のために「-fPIC」、リンカは"共通"のシンボルを共有ライブラリ内に持つことは認めないので「-fno-common」をつけてオブジェクトファイルを生成
gcc -fno-common -fPIC -Wall -g -c libhello.c動的ライブラリなので「-bundle」、後方互換のために「-flat_namespace」、ホストプログラムのシンボルを使うため「-undefined suppress」
gcc -bundle -flat_namespace -undefined suppress -o libhello.so libhello.oでは、実行ファイルを生成。内部で呼びだすのでlibhelloは必要ない、そのかわりに「dllfunc.h」を使うための「libdl」をリンクしておく。
gcc -g -o demo_use_dynamic demo_dynamic.o -ldl
PR
トラックバック
URL :
コメント
