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 -llua
run:
        lua test.lua
clean:
        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 Comments

  • 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以降のどこかの時点で変更が入ったということのようでした。
    情報ありがとうございました。

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.