LoginSignup
2
2

More than 5 years have passed since last update.

libcallの使い方まとめ

Last updated at Posted at 2014-06-12

libcall (or libcallnr) は、動的ライブラリの関数を呼び出すことができる。
ここでは以下について述べる。

  1. vim scriptからlibcallで動的ライブラリを呼び出す方法
  2. libcallで呼ぶことのできる動的ライブラリの作成方法

vim scriptからlibcallで動的ライブラリを呼び出す

libcallから呼び出すことのできる動的ライブラリ内の関数シグニチャは、

  • {char*,int} cdecl hoge({char*,int})

でなければならない。
libcallを実際に使う際には、

" char* cdecl some_func(char*)を呼び出す場合
" *nix系の場合 => 拡張子まで含めたファイルパスを指定
echo libcall('path/to/shared-object.so', 'some_func', 'string to be passed')
" windowsの場合 => 拡張子を含めないファイルパスを指定
echo libcall('path/to/dynamic-link-library', 'some_func', 'string to be passed')

とする。
libcallの第一引数には動的ライブラリのファイルパスを指定、第二引数には呼び出す関数名を指定する。
第三引数には、文字列か整数を渡す必要がある。

libcallとlibcallnrの使い分けとしては、呼び出す関数の返り値がchar*かintかで分ける。

libcallで呼ぶことのできる動的ライブラリの作成方法

関数宣言時の注意点は以下。

  1. 呼び出し規約はcdeclを使用する
  2. 引数は厳密に1つのみ、以下の型で受け取る
    • char*
    • int
  3. 返り値は以下の型のみ使用できる
    • char*
    • int

返り値としてchar*を使用する場合、vim側でfreeは行われないため、動的ライブラリ側でfreeする必要がある。
また通常の動的ライブラリと同様、動的ライブラリ内でデータを保持することができる。
ただし動的ライブラリ側でdlopen()し、自分自身をロードしなければならない。これについては次節で。

shared objectの場合は、コンパイルオプションに-fPICを指定する必要がある。
dynamic link libraryの場合は、__declspec(dllexport)する必要がある。

動的ライブラリ内でデータを保持する方法

動的ライブラリ内でデータを保持する場合、

  • *nix系

    dlopen()で自身をロードし、終了時にdlclose()する必要がある。

  • windows系

    LoadLibrary()で自身をロードし、終了時にFreeLibraryする必要がある。

このように、自身をロードしておかないと、libcall()での呼び出しごとに動的ライブラリの初期化と破棄を
繰り返すことになる。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2