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

共有ライブラリ

UNIXシステムコール Sample

共有ライブラリは、実行時に動的にリンクできるライブラリで、呼び出す関数の形式が変わらなければ、リンクせずに共有ライブラリを差し替えるだけで関数内の動作を変えることができる・・・。

とあるエンジニアの備忘log: Shared Object 入門

2つの共有ライブラリを作成し、リンクせずに差し替えるだけで動作が変わるかを検証する・・・。

まず、main関数のあるmain.cは、

関数funcを呼び出しており、funcの定義があるfunc.cは、

"func!"と出力した後に、関数sharedを呼ぶ・・・。
このsharedの実装を共有ライブラリとする・・・。

まず1パターン目・・・。
shared_1.cに、

というように、関数sharedは"shared_1!"を出力するように定義しておく・・・。

このパターンの共有ライブラリlibshared.soを"-shared -fPIC"オプションで作成・・・。

$ ls
func.c  func.h  main.c  shared.h  shared_1.c  shared_2.c
$ gcc -shared -fPIC -o libshared.so shared_1.c
$ ls
func.c  func.h  libshared.so  main.c  shared.h  shared_1.c  shared_2.c
$

これをひとまずlibshared.so.1としておく・・・。

$ mv libshared.so libshared.so.1
$ ls
func.c  func.h  libshared.so.1  main.c  shared.h  shared_1.c  shared_2.c
$

次に2パターン目・・・。
shared_2.cに、

というように、関数sharedは"shared_2!"を出力するように定義しておく・・・。

このパターンの共有ライブラリlibshared.soを"-shared -fPIC"オプションで作成・・・。

$ ls
func.c  func.h  libshared.so.1  main.c  shared.h  shared_1.c  shared_2.c
$ gcc -shared -fPIC -o libshared.so shared_2.c
$ ls
func.c  func.h  libshared.so  libshared.so.1  main.c  shared.h  shared_1.c  shared_2.c
$

これもひとまずlibshared.so.2としておく・・・。

$ mv libshared.so libshared.so.2
$ ls
func.c  func.h  libshared.so.1  libshared.so.2  main.c  shared.h  shared_1.c  shared_2.c
$

これで2つの共有ライブラリができたので、順に試してみる・・・。

$ ls
func.c  func.h  libshared.so.1  libshared.so.2  main.c  shared.h  shared_1.c  shared_2.c
$ mv libshared.so.1 libshared.so
$ ls
func.c  func.h  libshared.so  libshared.so.2  main.c  shared.h  shared_1.c  shared_2.c

libshared.so.1をlibshared.soに戻して、

$ gcc -o shared_library main.c func.c -Wl,-R$PWD -L. -lshared
$ ls
func.c  func.h  libshared.so  libshared.so.2  main.c  shared.h  shared_1.c  shared_2.c  shared_library
$

とすると、libshared.soをリンクした実行ファイルshared_libraryができる・・・。
(「リンクせずに」と言ったけど、最初に実行ファイルを作る時だけリンクは必要・・・。ライブラリを差し替える時は不要・・・。)
"-R$PWD"の"$PWD"は、カレントディレクトリ( = $PWD)に共有ライブラリがあるということ・・・。

まず、これで実行してみると、

$ ls
func.c  func.h  libshared.so  libshared.so.2  main.c  shared.h  shared_1.c  shared_2.c  shared_library
$ ./shared_library
func!
shared_1!
$

"func!"の後に、"shared_1!"を出力している・・・。

次に、libshared.so.2に差し替える・・・。

$ ls
func.c  func.h  libshared.so  libshared.so.2  main.c  shared.h  shared_1.c  shared_2.c  shared_library
$ mv libshared.so libshared.so.1
$ mv libshared.so.2 libshared.so
$ ls
func.c  func.h  libshared.so  libshared.so.1  main.c  shared.h  shared_1.c  shared_2.c  shared_library
$

これでそのまま実行すると、

$ ./shared_library
func!
shared_2!
$

"func!"の後に、ちゃんと"shared_2!"を出力している・・・。
これで共有ライブラリはリンクなしに差し替え可能であることがわかる・・・。

Sample/main.c at master · bg1bgst333/Sample · GitHub
Sample/func.h at master · bg1bgst333/Sample · GitHub
Sample/func.c at master · bg1bgst333/Sample · GitHub
Sample/shared.h at master · bg1bgst333/Sample · GitHub
Sample/shared_1.c at master · bg1bgst333/Sample · GitHub
Sample/shared_2.c at master · bg1bgst333/Sample · GitHub