luaとcの相互作用について簡単に説明します。
はじめに
luaとcの親密度は仮想スタックに依存しています。luaはこの仮想スタックを使用してcとの間で値を受け渡しします。スタックの各要素はluaの値(nil, number, string...)です。
luaがc関数を呼び出すと、c関数自身のスタックからもlua自身のスタックからも独立した、新しいスタックを取得します。このスタックには、luaがc関数に渡したい全ての引数が格納されています。c関数は次に、返された結果をこのスタックに格納し、呼び出し元に返します。
スタッククエリの操作については、スタックのルールに従えば、スタックの一番上にある要素しか取得できない。しかし、ここでは通常のスタックと異なる点があります。それは、インデックスを使って、スタック上の任意の要素を指し示すことができることです。正の数 (1.. .n) のインデックスは、スタックの下から上へ、1 はスタックの最初の要素、n はスタッ クの一番上の要素を指し、負の数 (-1...-n) はスタックの上から下へ、-1 はスタックの一番上の要素、-n はスタックの一番上の要素 を指します。この 2 つのインデックスの付け方で,スタックの中の要素を簡単に得ることができる.
基本操作
luaとcの橋渡しをするのが仮想スタックで、luaのc apiではlua_Stateと呼ばれています。以下のコードは、スタックを作成し、スタックに要素を追加し、インデックスに従ってスタック内の要素の値を取得するという、lua_Stateの最も基本的な操作を行っているところです。
lua_State *L = luaL_newstate();//create a new stack
lua_pushstring(L, "muzixiaoxin"); //push a string onto the stack
lua_pushnumber(L, 875);//push an integer onto the stack
//now there are two elements on the stack, the bottom of the stack is the string "muzixiaoxin", the top of the stack is the integer 875
//"muzixiaoxin" the index is 1, or -2
//the index of 855 is 2, or -1
if (lua_isstring(L, 1)){//Determine if the element at the bottom of the stack is a string
printf("%s\n",lua_tostring(L, 1));//If it is a string, convert to string output
}
if (lua_isnumber(L, -1)){//Determine if the element at the top of the stack is of type number
printf("%d", lua_tonumber(L, 2));//if it's a number, output it as a number
}
lua_close(L); //remember to release when not needed
c コールルア
luaの呼び出しはあまり見たことがなく、通常はlua VMが直接スクリプトを実行しています。cの設定ファイルとしてluaを使用しているものもあります。
例として、新しいluaファイルtest.luaを作成します。
name = "muzixiaoxin"
version = 1003
cはこのファイルをlua c apiを通して読み込み、実行する必要があります。実行結果はスタックにあり、このスタックに移動して変数の値を取得します。
次のCのコードを見てください。
lua_State *L = luaL_newstate();
int err = luaL_loadfile(L, "test.lua"); //load the lua file as a block of code, just load it without running it
if (err){
return;
}
err = lua_pcall(L, 0, 0, 0);//run the loaded code block
if (err){
return;
}
lua_getglobal(L, "name"); //press the value of the global variable name to the top of the stack
printf("%s\n", lua_tostring(L, -1));//take out the top element of the stack and print the result as:muzixiaoxin
lua_close(L); //remember to release when not needed
lua は c メソッドを呼び出します。
luaがcを呼び出すのは、luaが呼び出す固定フォーマットのメソッドを書くのが少し厄介です。
まずは単純に和算のcメソッドを書いてみましょう。
// Calculate the summation method
static int
sum(int a, int b){
return a + b;
}
このメソッドは、2つの整数の和を求めるものです。luaにこのメソッドを使わせるには、このメソッドをluaステートマシンに登録する必要がありますが、luaステートマシンに登録するメソッドは、固定パラメータと固定戻り値を必要とし、パラメータは、luaから渡されたパラメータを格納するlua仮想スタック、lua呼び出しの戻り値は、この仮想スタックを介してluaに返す必要があり、最終戻り値は、luaに返す変数の数を格納するインテ値でなければなりません。書かれたメソッドを見てみましょう。
//lua calls the method
static int
lsum(lua_State *L){
int a = (int)lua_tonumber(L, -1);//one of the parameters of the lua call
int b = (int)lua_tonumber(L, -2);//one of the arguments to the lua call
lua_pushnumber(L, sum(a, b));//add the calculated to the stack
return 1;//return the number of returned values
}
次のステップは、メソッドlsumをluaステートマシンに登録することです。
lua_State *L = luaL_newstate();
luaL_openlibs(L);//open all the standard libraries in L so that you can use the print method
lua_register(L, "sum", lsum);//register the c function lsum as a global variable sum of lua
int err = luaL_dofile(L, "test.lua"); //load the lua file as a block of code and run it
if (err){
return;
}
lua_close(L);
test.luaの中身は。
print("1 + 2 = " . sum(1,2))
最終的に出力されるのは
1+2=3
要約すると、luaの仮想スタックを中間関数(lsumなど)で操作して、cのlua呼び出しを実装する必要があるということです。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン