gpt4 book ai didi

c++ - Lua C API - 使用同名的变量和函数加载多个文件

转载 作者:行者123 更新时间:2023-12-01 14:52:47 26 4
gpt4 key购买 nike

假设我有两个 Lua 文件,我将从标准 Lua C API 使用它们,它们共享一个公共(public)库:

common.lua

function printHello(name)
print("Hello from " .. name)
end

文件1.lua
require "common"
local scriptName = "file1"

function doSomething()
printHello(scriptName)
end

文件2.lua
require "common"
local scriptName = "file2"

function doSomething()
printHello(scriptName)
end

现在说我想让两个 file*.lua 文件共享 相同 lua_State . 无需更改任何 Lua 代码 , 我怎样才能加载文件以便我可以调用特定的 doSomething() ?

有没有办法可以将“所有内容”从加载的文件(函数、变量、表)中移动到 lua_State 中的全局表中?使用脚本名称(或其他)作为键?另外,有没有办法让 file1.lua 和 file2.lua 可以共享 common.lua 的“内存”版本?

我正在使用 Lua 5.1。

谢谢!

最佳答案

以下是在纯 Lua 5.1 中的操作方式:

file1_env = setmetatable({}, {__index = _G})
local file1_chunk = loadfile('file1.lua')
setfenv(file1_chunk, file1_env)
file1_chunk()

file2_env = setmetatable({}, {__index = _G})
local file2_chunk = loadfile('file2.lua')
setfenv(file2_chunk, file2_env)
file2_chunk()

file1_env.doSomething() -- prints "Hello from file1"
file2_env.doSomething() -- prints "Hello from file2"

发生的事情是您正在更改每个文件的 block 运行的环境,所以而不是把它们的 doSomething在全局环境中运行并因此相互踩踏,它们进入自己的本地环境(使用元表,因此它们可以使用全局环境中的东西,如 requireprint )。根据要求, common.lua只需要运行一次,你会看到你是否放了 printHello('common') 之类的东西最后。

如果您想从 C 中执行此操作,我使用的所有功能都可以直接转换为 C API,如下所示:

#include <lua5.1/lua.h>
#include <lua5.1/lualib.h>
#include <lua5.1/lauxlib.h>

int main(void) {
lua_State *L = luaL_newstate();
luaL_openlibs(L);

/* stack is empty */
lua_createtable(L, 0, 1);
/* -1: file1_env */
lua_createtable(L, 0, 1);
/* -2: file1_env, -1: file1_env_mt */
lua_pushvalue(L, LUA_GLOBALSINDEX);
/* -3: file1_env, -2: file1_env_mt, -1: _G */
lua_setfield(L, -2, "__index");
/* -2: file1_env, -1: file1_env_mt */
lua_setmetatable(L, -2);
/* -1: file1_env */
luaL_loadfile(L, "file1.lua");
/* -2: file1_env, -1: file1_chunk */
lua_pushvalue(L, -2);
/* -3: file1_env, -2: file1_chunk, -1: file1_env */
lua_setfenv(L, -2);
/* -2: file1_env, -1: file1_chunk */
lua_call(L, 0, 0);
/* -1: file1_env */
lua_setglobal(L, "file1_env");
/* stack is empty */
lua_createtable(L, 0, 1);
/* -1: file2_env */
lua_createtable(L, 0, 1);
/* -2: file2_env, -1: file2_env_mt */
lua_pushvalue(L, LUA_GLOBALSINDEX);
/* -3: file2_env, -2: file2_env_mt, -1: _G */
lua_setfield(L, -2, "__index");
/* -2: file2_env, -1: file2_env_mt */
lua_setmetatable(L, -2);
/* -1: file2_env */
luaL_loadfile(L, "file2.lua");
/* -2: file2_env, -1: file2_chunk */
lua_pushvalue(L, -2);
/* -3: file2_env, -2: file2_chunk, -1: file2_env */
lua_setfenv(L, -2);
/* -2: file2_env, -1: file2_chunk */
lua_call(L, 0, 0);
/* -1: file2_env */
lua_setglobal(L, "file2_env");
/* stack is empty */
lua_getglobal(L, "file1_env");
/* -1: file1_env */
lua_getfield(L, -1, "doSomething");
/* -2: file1_env, -1: file1_env.doSomething */
lua_call(L, 0, 0);
/* -1: file1_env */
lua_pop(L, 1);
/* stack is empty */
lua_getglobal(L, "file2_env");
/* -1: file2_env */
lua_getfield(L, -1, "doSomething");
/* -2: file2_env, -1: file2_env.doSomething */
lua_call(L, 0, 0);
/* -1: file2_env */
lua_pop(L, 1);
/* stack is empty */

lua_close(L);
return 0;
}

关于c++ - Lua C API - 使用同名的变量和函数加载多个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61683579/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com