luaとcのインタラクション
2398 ワード
Luaは軽量で柔軟で拡張性の高いスクリプト言語であり、他の言語(C/C++)に簡単に埋め込むことができます.これは主に強力なC APIを提供しているおかげで、C/C++との相互調整が容易になります.
Lua呼び出しC
LuaはC関数を呼び出し、実はC関数をLuaに登録し、C関数アドレスをLua解釈器に渡す.この伝達は、次のプロトコルに従います.
1
LuaとCはスタック(State)によって相互作用し,LuaがC関数を呼び出すと,まずLuaがスタックにデータをコピーし,その後Cがスタックからデータを取得し,呼び出しが終了すると戻り結果をスタックに格納する.スタック内の各データはインデックス値によって位置決めされ、インデックス値が正の場合はスタックの底に対するオフセットインデックスを表し、インデックス値が負の場合はスタックの頂部に対するオフセットインデックスを表し、インデックス値は1または-1を開始値とするため、スタックの頂部インデックス値は永遠に-1であり、スタックの底部インデックス値は永遠に1である.スタックはLuaとCの間のデータの中継局に相当し、各C関数には独自のプライベートスタックがある.
Luaが提供するC APIを利用して、C関数を呼び出すのは簡単です.例えば、次の例です.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
上のコードを静的リソースのsoファイルにコンパイルし、上のコードをmylibという名前に保存します.cのファイルの下でlibmylibという名前にコンパイルします.soの静的リソースファイルでは、gccコンパイル文は以下の通りです.
1
上のコードをLUAに置くCPATHディレクトリの下(LUA_CPATHディレクトリの位置説明は『Lua学習ノート(4)--モジュールとパッケージ』を詳しく見て、ここではあまり言わない).
libmylib.soリソースファイルをモジュールディレクトリにロードすると、Luaコードにrequireを直接ロードして使用できます.例えば、次のように使用します.
1
2
Lua呼び出しC
LuaはC関数を呼び出し、実はC関数をLuaに登録し、C関数アドレスをLua解釈器に渡す.この伝達は、次のプロトコルに従います.
1
typedef int (*lua_CFunction)(lua_State* L)
LuaとCはスタック(State)によって相互作用し,LuaがC関数を呼び出すと,まずLuaがスタックにデータをコピーし,その後Cがスタックからデータを取得し,呼び出しが終了すると戻り結果をスタックに格納する.スタック内の各データはインデックス値によって位置決めされ、インデックス値が正の場合はスタックの底に対するオフセットインデックスを表し、インデックス値が負の場合はスタックの頂部に対するオフセットインデックスを表し、インデックス値は1または-1を開始値とするため、スタックの頂部インデックス値は永遠に-1であり、スタックの底部インデックス値は永遠に1である.スタックはLuaとCの間のデータの中継局に相当し、各C関数には独自のプライベートスタックがある.
Luaが提供するC APIを利用して、C関数を呼び出すのは簡単です.例えば、次の例です.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <math.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static
int
l_sin (lua_State *L)
{
double
d = luaL_checknumber(L, 1);
lua_pushnumber(L,
sin
(d));
return
1;
}
static
const
struct
luaL_Reg mylib [] = {
{
"lsin"
, l_sin},
{NULL, NULL}
};
int
luaopen_mylib(lua_State *L)
{
luaL_openlib(L,
"mylib"
, mylib, 0);
return
1;
}
上のコードを静的リソースのsoファイルにコンパイルし、上のコードをmylibという名前に保存します.cのファイルの下でlibmylibという名前にコンパイルします.soの静的リソースファイルでは、gccコンパイル文は以下の通りです.
1
gcc mylib.c -fPIC -shared -o libmylib.so
上のコードをLUAに置くCPATHディレクトリの下(LUA_CPATHディレクトリの位置説明は『Lua学習ノート(4)--モジュールとパッケージ』を詳しく見て、ここではあまり言わない).
libmylib.soリソースファイルをモジュールディレクトリにロードすると、Luaコードにrequireを直接ロードして使用できます.例えば、次のように使用します.
1
2
require
"mytestlib"
print
(mylib1.lsin(
10
))