1

私はこの主題を調査し、さまざまなアプローチを試みましたが、私が考えている動作を実装することはできません (それが可能かどうかさえわかりません)。基本的に、次のように、メタテーブルからアクセスできる C で作成されたいくつかのユーザーデータ オブジェクトがあります。

Main.lua

config.display_width = 1280

私がやりたいのは、構成名前空間を特定のスクリプトに「強制」することです。ご想像のとおり、ユーザーが構成メタテーブルのみを扱うように制限されるように、構成ファイルを保護する必要があります。このような:

Config.lua

display_width = 1280

そして、私はCで次のようなことをしなければならないことを知っています:

// Register the config metatable and its methods
luaL_loadfile(L, "my_config.cfg");
lua_getglobal(L, "config"); // Is this necessary?
lua_setfenv(L, -2); // I know this has to be used, but how?
lua_pcall(L, 0, 0, 0);

前もってありがとう、これは私を夢中にさせています!

PS: 記録のために、C 構造にバインドされているため、構成ユーザーデータをそのままにしておく必要があります。結果として、異なる環境間で Lua の状態や宣言された変数が「失われる」ことについては心配していません。

以下の情報を追加します。これは、構成ユーザーデータの作成方法です。

const struct luaL_Reg metaconfig[] =
{
    {"__index", l_get},
    {"__newindex", l_set},
    {NULL, NULL}
};

lua_newuserdata(L, sizeof(void *));

luaL_newmetatable(L, "metaconfig");
luaL_register(L, NULL, metaconfig);
lua_setmetatable(L, -2);

lua_setglobal(L, "config");

したがって、ユーザーが構成ユーザーデータから値を設定または取得するたびに、__indexまたは__newindexメソッドを介して C 構造を更新します。

4

1 に答える 1

1

構成テーブルを表すグローバルは実際には必要ありません。lua_refを使用して行うこともできます。

ここでこれは期待どおりに機能します(私は推測します):

#include <lua.h>
#include <lauxlib.h>
#include <stdlib.h>

int main (void){
    int idxConfig, res;
    lua_State *L = luaL_newstate();
    if ((res = luaL_loadfile(L,"my_config.cfg")) != 0){//Load file
        printf("Got error code %d loading file my_config.cfg, exiting",res);
        exit(-1);
    }
    lua_newtable(L); // new config table
    lua_pushvalue(L,-1);// duplicate table
    idxConfig = lua_ref(L,LUA_REGISTRYINDEX); // take a reference to the table (pops it)
    lua_setfenv(L,-2); // pop table, set as environment for loaded chunk
    lua_call(L,0,0); // load config -- nothing on stack
    lua_rawgeti(L,LUA_REGISTRYINDEX,idxConfig); //push config table
    lua_getfield(L,1,"display"); //read out "display"
    lua_Integer disp_width = lua_tointeger(L,-1);
    printf("Display width = %d",(int) disp_width);
    lua_close(L);
    exit(0);
}
于 2011-02-15T15:36:56.467 に答える