Luaプログラミング入門 > 第8章 C言語との連携 > LuaからCを呼び出す > C関数を呼び出す


[Prev] [Next] [Up] [Contents][フレーム表示] [フレーム解除

C関数を呼び出す 応援する

Lua側からC言語の関数addを呼び出してみます.

Lua側では次のようなソースを書いたとします. Luaファイル名はsample.luaです.

--sample.lua

x,y = 5, 10
result = add(x, y)
print("x + y は " .. result .. " です")

ではC言語側の関数をお見せします.

#include <stdio.h>

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

int l_add(lua_State* L)
{
        //第1引数 intとして取得
        int x = luaL_checkint(L, -2);
        //第2引数
        int y = luaL_checkint(L, -1);
        int result = x + y;

        printf("%d + %d を計算します\n", x, y);

        //戻り値をスタックに積む
        lua_pushnumber(L, result);
        return 1; //戻り値の数を指定
}

int main (void)
{
        int x = 10, y = 5;

        //Luaを開く
        lua_State* L = luaL_newstate();
        //Luaの標準関数を使用できる状態にする
        luaL_openlibs(L);

        //l_add関数をadd関数としてLuaに登録
        lua_register(L, "add", l_add);

        //Luaファイルsample.luaを読み込む
        if( luaL_loadfile(L, "sample.lua") || lua_pcall(L, 0, 0, 0) ) {
                printf("sample.luaを開けませんでした\n");
                printf("error : %s\n", lua_tostring(L, -1) );
                return 1;
        }

        lua_close(L);
        return 0;
}

実行結果

5 + 10 を計算します
x + y は 15 です

Lua側でC言語関数を呼び出すと,l_add関数のLuaスタックに引数が積まれます. C言語側の引数に直接値が渡されるわけではないので注意してください. 第1引数は始めにプッシュされ,第2引数はその次にプッシュされます. よってC言語側からこのスタックの値を取得すればよいわけです.

スタックの値を取得する時にluaL_check***関数を使用しました. ***にはLua変数のデータ型が入ります. この関数は指定したスタックの値を***型であるかを判定してから取得します. もし***型で無かった場合はエラーが発生します.

試しにadd関数の第1引数に文字列を渡してみました. 結果は以下のようになりました.

実行結果

sample.luaを開けませんでした
error : sample.lua:4: bad argument #-2 to 'add' (number expected, got string)

l_add関数から戻り値を返す場合もLuaスタックに値を積みます. l_add関数の戻り値には戻り値の数を指定します.

さて,Lua側からC関数を呼び出すためには,Luaに関数を登録しなければなりません. その際使用するのがlua_register関数です.

void lua_register (lua_State *L, const char *name, lua_CFunction f);

nameにはLuaから呼び出す関数名を登録します. fにはC言語関数を渡します. 実はこの関数は以下のようにマクロとなっています.

 #define lua_register(L,n,f)  (lua_pushcfunction(L, f), lua_setglobal(L, n))

lua_pushcfunction関数はC言語関数fをスタックにプッシュするものです.


[Prev] [Next] [Up] [Contents][フレーム表示] [フレーム解除

このサイトについて|ヘルプ|Q&A|個人情報保護|プライバシーポリシー|利用規約|コメント・トラックバック規約|削除規程|広告掲載
Copyright (c) 2005-2007 Time Intermedia Corporation