2013年2月24日日曜日

[C]共有ライブラリ (Shared Libary, Windows では Dynamic Link Libary と呼称する) の作成方法

静的ライブラリ (Static library)
  • コンパイル時に組み込まれるライブラリ。拡張子は .a になる。
  • Static library を使用する場合は直接ライブラリを指定してコンパイルする。
    $ gcc test.c libtest.a
    
共有ライブラリ (Shared library)
  • プログラムの実行時にロードされるライブラリ。拡張子は .so や .sa になる。
  • Shared library を使用する場合はライブラリの検索パスに使用するライブラリを配置し、-l オプションでライブラリを指定してコンパイルする。
    $ gcc test.c -lxxx
    
動的ライブラリ (Dynamic link)
  • 共有ライブラリの一種で、実行時に関数を使ってロード、アンロードできる。モジュールのロード位置に依存しないので gcc でコンパイルする時に -fPIC オプションをつける。

libtest.c を共有ライブラリにする
  1. libtest.c 作成
    /* libtest.c */
    #include <stdio.h>
    #include "libtest.h"
    
    int lib_function(char *str)
    {
      printf("Hello, %s\n", str);
    
      return 0;
    }
    
  2. libtest.c をコンパイルしてオブジェクト (libtest.o) を生成する。動的ライブラリとして使用するために -fPIC オプションをつける。
    $ gcc -fPIC -c libtest.c
    
  3. libtest.o から共有ライブラリ (libtest.so) を生成する。
    soname により libtest.so.1 という名前でもロードできるようにする。
    $ gcc -shared -Wl,-soname,libtest.so.1 -o libtest.so.1.0 libtest.o
    
  4. libtest.so.1 という名前で libtest.so.1.0 に対してシンボリックリンクを張る。
    $ ln -s libtest.so.1.0 libtest.so.1
    
  5. libtest.so.1.0 を使用する test_sl.c を作成する。shared library を呼び出すための関数郡である dl ライブラリ (dlfcn.h) を読み込んでおく。
    dlopen() にある RTLD_LAZY は「シンボルの解決はシンボルを参照するコードが実行される時に解決を行う」ということを表す。
    dlsym() では dlopen() が返した Dynamic library のハンドルを通して lib_function というシンボルを呼び出している。
    #include <stdio.h>
    #include <dlfcn.h>
    
    int main(void)
    {
      void *libtest;
      void (*test_call)();
    
      libtest = dlopen("./libtest.so.1.0", RTLD_LAZY);
      if (libtest == NULL) {
        printf("Fail to dlopen()\n");
        return -1;
      }
      test_call = dlsym(libtest, "lib_function");
      (*test_call)("hogehoge");
    
      return 0;
    }
    
  6. dl ライブラリをリンクしてコンパイルする。
    $ gcc -o test_sl.out test_sl.c -ldl
    

0 件のコメント:

コメントを投稿