C++のプログラムから共有ライブラリを呼び出す方法(Linux編)

Windows編macOS編から引き続いてLinux編です。といっても、macOS編とかなり近い部分があります。

暗黙的リンク

まずはこちらから。g++は少々古いですが4.7.2を使っております。プログラムはshared.ccとして

#include <iostream>

void hoge() 
{
    std::cout << "Hello Hoge!\n"; 
}

ヘッダファイルもshared.hとして

void hoge();

作成します。プログラム自体はmacOSと全く同じで、コンパイルの仕方が少々異なります。

g++ -shared -fPIC -o shared.so shared.cc

PICオプション(Position Independent Code)についてはこちらのサイトが詳しいです。

呼ぶ側のコード(tmp.cc)もmacOS版と全く同じで

#include "shared.h"

int main(){
  hoge();
  return 0; 
}

として、

g++ shared.so tmp.cc

shared.soを渡してやります。最後の実行時に、このshared.soの置き場所が環境変数LD_LIBRARY_PATHに入っているかどうか確認をし

echo $LD_LIBRARY_PATH

入っていなければ、追加をします(以下ではbash系を想定してカレントディレクトリを追加)。

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

最後にいつものように

./a.out

でいつもの文字が表示されるはずです。

参考サイト

dyama’s page

明示的リンク

こちらもmacOS版とコンパイルのコマンドのみが違い、ライブラリ側の名前修飾への対応と呼び出し側での関数ポインタの取得を行います。ライブラリ側のファイル名はshared.ccとして、ヘッダファイルは要りません。

#include <iostream> 
extern "C" void hoge()
{
  std::cout << "Hello Hoge!\n"; 
}

コンパイルは以下で行います。暗黙的リンクと全く同じですが、macOSとは少々異なります。

g++ -shared -fPIC -o shared.so shared.cc

次に呼び出し側のプログラム(tmp.cc)です。macOSと全く同じです。

#include <dlfcn.h>

using HOGE_FUNCTION = void (*)(void);

int main()
{
  void *ptrHandle = dlopen("shared.so", RTLD_LAZY);
  HOGE_FUNCTION ptrDllFunc = (void (*)(void))dlsym(ptrHandle, "hoge");
  ptrDllFunc();
  return 0;
}

コンパイルは以下で行います。

g++ -ldl -std=c++11 tmp.cc

usingのためのc++11指定の他、動的ロードのためのdlライブラリを指定しております。さすがに今回は実行のコマンドは省略します。あと実際のプログラムで使う際にはdlerror関数などでエラーを取得などするといいと思いますが、詳細は以下の参考サイトなどをご覧ください。それではlet’s enjoy hoge!

さてと、ここまで書いたら何がしたかったかそろそろばれてそうですが、要するにWindows、macOS、Linuxで共通して使える明示的ライブラリ動的読み込みプログラムを作りたかったんです。処理の流れはほとんど同じなので、プリプロセッサによる分岐で十分対応可能と思います。そこまでやるかどうかは分かりませんが、気が向けばまとめたいと思います。

参考サイト

C++ dlopen mini HOWTO

コメント

タイトルとURLをコピーしました