読者です 読者をやめる 読者になる 読者になる

静的ライブラリと共有ライブラリの整理 - その1 -

概要

C言語における静的ライブラリと共有ライブラリの作成・使用方法を整理.

  • 静的ライブラリ
    • コンパイル時にリンクする
    • ファイル名は libxxx.a (Windows なら xxx.lib)
    • オブジェクトファイルを ar コマンドを使用して作成
  • 共有ライブラリ
    • プログラム実行時にリンクする
    • ファイル名は libxxx.so (Windows なら xxx.dll)
    • コンパイラごとに作成方法が変わる(?) ※ 今回は gcc を使用
    • nm で libxxx.so に関数が登録できたか確認可能

ライブラリにするコード(サンプル)

  • ヘッダーファイル
//hoge.h
#ifndef _HH_HOGE_
#define _HH_HOGE_
void test(void);
#endif
  • ライブラリにする関数(サンプルなので適当)
//hoge.c
#include "hoge.h"
#include <stdio.h>

void test(void){
  printf("hoge.c: test\n");
}

静的ライブラリ

静的ライブラリの作成方法
# オブジェクトファイルを作成する
$  gcc-mp-4.8 hoge.c -c

# 静的ライブラリを作成
$ ar r libhoge.a hoge.o

# オブジェクトファイルがあるか確認する
$ ar t libhoge.a
__.SYMDEF SORTED
hoge.o
静的ライブラリの使用方法
//main.c
#include <stdio.h>
#include "hoge.h"

int main(void){

  test();

  return 0;
}
コンパイル方法と実行結果
$ gcc-mp-4.8 main.c -L ./ -l hoge 
$ ./a.out
hoge.c: test

共有ライブラリ

共有ライブラリの作成方法
# コンパイルで libhoge.so を作成する
$ gcc-mp-4.8 -shared -fPIC hoge.c -o libhoge.so

# libhoge.so に test 関数があるか確認
$ nm libhoge.so
                 U _puts
0000000000000f70 T _test    # test があるのでOK 
                 U dyld_stub_binder
共有ライブラリの使用方法
//main.c
#include <stdio.h>
#include <dlfcn.h>

typedef void (*hoge_test)(void);

int main(void){
  void* handle = NULL;
  hoge_test func = NULL;
  
  do{
    //libhoge.so をオープン
    handle = dlopen("./libhoge.so", RTLD_LAZY);
    if(handle == NULL){
      fprintf(stderr, "error: dlopen(%d)\n", dlerror());
      break;
    }
    
    //関数ポインタに test を格納
    func = (hoge_test)dlsym(handle, "test");
    if(func == NULL){
      fprintf(stderr, "error: dlsym(%d)\n", dlerror());
      break;
    }
    
    //test を呼ぶ
    func();
  } while(0);

  //handle をクローズ
  if(handle != NULL){
    if(dlclose(handle) != 0){
      fprintf(stderr, "error: dlclose(%d)\n", dlerror());
      return -3;
    }
  }

  return 0;
}
コンパイル方法と実行結果
$ gcc-mp-4.8 main.c -ldl
$ ./a.out
hoge.c: test