いわて駐在研究日誌2。

NEVER STAND BEHIND ME

C++のダイナミックライブラリの作成・使用

 

$ more hello.cpp
#include<iostream>
#include<stdio.h>

using namespace std;

int hello(){
   cout<<"Hello,World!"<<endl;

}

linuxC++でのdynamic linkライブラリ(.so)の作り方

g++ -shared -fPIC -o libhello.so hello.cpp

メモ:

  • fPICオプションは速度は遅くなるがつけたほうが良いらしい。
  • nmコマンドでシンボルテーブルを確認できる。
  • $ nm libhello.so

    0000000000200c70 d DW.ref.__gxx_personality_v0
    0000000000200a48 a _DYNAMIC
    0000000000200c30 a _GLOBAL_OFFSET_TABLE_
    00000000000008f2 t _GLOBAL__I_hello.cpp
                     w _Jv_RegisterClasses
    00000000000008aa t _Z41__static_initialization_and_destruction_0ii
    000000000000087c T _Z5hellov
                     U _ZNSolsEPFRSoS_E@@GLIBCXX_3.4
                     U _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4
                     U _ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4
                     U _ZSt4cout@@GLIBCXX_3.4
                     U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4
    0000000000200c88 b _ZStL8__ioinit
                     U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@@GLIBCXX_3.4
    0000000000200a20 d __CTOR_END__
    0000000000200a10 d __CTOR_LIST__
    0000000000200a30 d __DTOR_END__
    0000000000200a28 d __DTOR_LIST__
    0000000000000a08 r __FRAME_END__
    0000000000200a38 d __JCR_END__
    0000000000200a38 d __JCR_LIST__
    0000000000200c78 A __bss_start
                     U __cxa_atexit@@GLIBC_2.2.5
                     w __cxa_finalize@@GLIBC_2.2.5
    0000000000000910 t __do_global_ctors_aux
    00000000000007d0 t __do_global_dtors_aux
    0000000000200a40 d __dso_handle
                     w __gmon_start__
                     U __gxx_personality_v0@@CXXABI_1.3
    0000000000200c78 A _edata
    0000000000200c90 A _end
    0000000000000948 T _fini
    0000000000000738 T _init
    00000000000007b0 t call_gmon_start
    0000000000200c78 b completed.6349
    0000000000200c80 b dtor_idx.6351
    0000000000000850 t frame_dummy

 

linuxC++でのdaynamicライブラリ(.so)の利用の仕方

  • 呼び出す関数の頭にextern "C"を記述し、シンボル名をマングル(名前変更)されないようにしておく

extern "C" void func(void)
{
   cout << "This is Function" << endl;
}

  • 実行時にリンクする(-lオプションで頭のlib***と、.so拡張子を除いた部分を指定する。-Lでパスを指定する。-Iはinclude headerのパスを指定する)

g++ -I./ -L./ -o main main.cpp -lhello

  • もしくは、libdl.soを利用してプログラム中で動的にロードする
  • main.cpp中に#include <dlfcn.h>
  • g++ -I./ -L./ -o main main.cpp -ldl

#include <iostream>
#include <dlfcn.h>

using namespace std;
int main()
{
  void *handle = dlopen("./libhello.so", RTLD_LAZY);
  if (handle == 0) {
    cout <<  " dlopen error .... %s", dlerror() << endl;
  }

  void (*func)(void) = dlsym(handle, "func");
  if (func == 0) {
    cout <<  " dlsym error .... %s", dlerror() << endl;
  }

  hoge :: func();

  if (dlclose(handle) != 0) {

    cout <<  " dlclose error .... %s", dlerror() << endl;
  } 

return 0;

}