LuaからC言語の関数を呼び出す
2008/08/17
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で調べた情報から推測しながらでもなんとか書けました。という状態なので、間違っている部分や良くない部分がありましたら、詳しい方の突っ込みお待ちしてます。
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以降のどこかの時点で変更が入ったということのようでした。
情報ありがとうございました。