LuaからC言語の関数を呼び出す

http://d.hatena.ne.jp/smeghead/20080816/sl で、SLを書いたときにLuaにsleep関数が存在していないらしいことに驚きました。

Cと親和性が高いLuaなので、丁度いい練習になると思い、Luaから呼び出せるsleep関数を作ってみました。

lsleepモジュール

lsleepモジュールとして作成しました。ソースは下の一個だけ。とりあえず、Luaでrequireして、requireしたモジュールの関数を呼び出すことのための最小限だけを書いています。細かい話は、たいぶ省略していると思います。

lsleep.c
#include<stdio.h>#include<lua.h>#include<lualib.h>#include<lauxlib.h>#include<unistd.h>/* Luaからsleepとして参照する関数 */static int lsleep(lua_State* L)
{int second = lua_tonumber(L, 1);
sleep(second);return 1;
}/* Luaからusleepとして参照する関数 */static int lusleep(lua_State* L)
{int microsecond = lua_tonumber(L, 1);
usleep(microsecond);return 1;
}/* lsleepモジュールに登録する関数のマッピング定義 */static const struct luaL_reg lsleeplib[] = {
{"sleep", lsleep},
{"usleep", lusleep},
{NULL, NULL},
};/* lsleepモジュール初期化関数 */int luaopen_lsleep(lua_State* L)
{
luaL_openlib (L, "lsleep", lsleeplib, 0);return 1;
}

Makefile

lsleep.so: lsleep.c
gcc -O -o lsleep.so -shared lsleep.c -lluarun:lua test.luaclean:rm lsleep.so

makeすると、lsleep.soを作成します。

test.lua

lsleep.sleep(1) と lsleep.usleep(1000000) は、共に1秒間待ちます。

require "lsleep"print('test.lua will sleep.')
lsleep.sleep(1)print('test.lua will usleep.')
lsleep.usleep(1000000)print('test.lua will end.')

今回、Cのsleep関数とusleep関数を呼び出しただけですが、逆にLuaとCの接合部が簡単であったのがよくわかりました。手元に、Luaの本は無かったけど、lfsというライブラリのソースとWebで調べた情報から推測しながらでもなんとか書けました。という状態なので、間違っている部分や良くない部分がありましたら、詳しい方の突っ込みお待ちしてます。

2件のコメント

  • Lua 5.1だと
    lua_register(L, "lsleep", lsleeplib);
    ですね

  • コメントありがとうございます。
    今、Ubuntu10.04のパッケージ管理でインストールされるLua5.1.0で試したところ、変更せずに動作しました。ライブラリのパスなどは調整しましたが。

    ちょっと検索してみたところ
    http://sugarpot.sakura.ne.jp/yuno/html/lua51_manual_ja.html
    関数 luaL_openlib は luaL_register に置き換えられた。
    とありました。このことだったのですね。
    5.1.0以降のどこかの時点で変更が入ったということのようでした。
    情報ありがとうございました。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください