从C 访问功能环境中的LUA变量
Accessing Lua variable in function environment from C++
这可能是一个简单的问题,但我很难过。这是针对LUA 5.1。
我有一个在自己的环境中运行的脚本。在那个环境中,我有一个称为"插件"的变量,我从c 设置了这样的变量:
lua_getfield(L, LUA_REGISTRYINDEX, getScriptId()); // Put script's env table onto the stack -- env_table
lua_pushstring(L, "plugin"); // -- env_table, "plugin"
luaW_push(L, this); // -- env_table, "plugin", *this
lua_rawset(L, -3); // env_table["plugin"] = *this -- env_table
lua_pop(L, -1); // Cleanup -- <<empty stack>>
在运行LUA脚本之前,我将功能环境设置为这样:
lua_getfield(L, LUA_REGISTRYINDEX, getScriptId()); // Push REGISTRY[scriptId] onto stack -- function, table
lua_setfenv(L, -2); // Set that table to be the env for function -- function
当我的脚本运行时,它可以按预期看到并与插件变量进行交互。到目前为止,一切都很好。
在某一时刻,LUA脚本称为C 函数,在该功能中,我想看看是否设置了插件变量。
我尝试了很多事情,而且我似乎看不到插件变量。这只是我尝试的4件事:
lua_getfield(L, LUA_ENVIRONINDEX, "plugin");
bool isPlugin = !lua_isnil(L, -1);
lua_pop(L, 1); // Remove the value we just added from the stack
lua_getfield(L, LUA_GLOBALSINDEX, "plugin");
bool isPlugin2 = !lua_isnil(L, -1);
lua_pop(L, 1); // Remove the value we just added from the stack
lua_getglobal(L, "plugin");
bool isPlugin3 = !lua_isnil(L, -1);
lua_pop(L, 1); // Remove the value we just added from the stack
lua_pushstring(L, "plugin");
bool isPlugin4 = lua_isuserdata(L, -1);
lua_pop(L, 1);
不幸的是,所有iSplugin变量返回false。好像来自LUA调用的C 函数无法在LUA环境中看到变量集。
知道我如何从C 看到插件变量?
谢谢!
lua中的每个函数都有其自己的环境。他们不会继承任何人称呼的环境。因此,如果您的C 函数不使用具有此plugin
变量的环境,则不会看到它。
您可以将环境作为闭合的一部分传递到C函数(请参阅lua_pushcclosure
)。我不知道您拥有的设置,但是我可以看到这可以解决的三种方法:
1)您的C函数在与函数相同的环境中注册 - 良好,将起作用。
2)您的C函数已在全球环境中注册,但是将其称为所有特定环境中的LUA函数 - 如果在函数注册时存在环境(可以将其添加到关闭中)。<<<<<<<<<<<<<<<<<<br>3)您的C功能已在全球环境中注册,可以通过在不同环境中工作的不同LUA函数来调用 -
如果是2或3,则如果更改使用变体1。
,可能没有缺点。编辑:好吧,这不会起作用。如果您愿意从LUA API中差一点,则可以获得一种获取地下信息的方法。免责声明:我正在使用5.2,所以我试图以5.1的方式调整方法。我无法测试,它可能不起作用。
首先您需要#include "lstate.h"
这是5.1中的lua_state结构:
struct lua_State {
CommonHeader;
lu_byte status;
StkId top; /* first free slot in the stack */
StkId base; /* base of current function */
global_State *l_G;
CallInfo *ci; /* call info for current function */
const Instruction *savedpc; /* `savedpc' of current function */
StkId stack_last; /* last free slot in the stack */
StkId stack; /* stack base */
CallInfo *end_ci; /* points after end of ci array*/
CallInfo *base_ci; /* array of CallInfo's */
int stacksize;
int size_ci; /* size of array `base_ci' */
unsigned short nCcalls; /* number of nested C calls */
lu_byte hookmask;
lu_byte allowhook;
int basehookcount;
int hookcount;
lua_Hook hook;
TValue l_gt; /* table of globals */
TValue env; /* temporary place for environments */
GCObject *openupval; /* list of open upvalues in this stack */
GCObject *gclist;
struct lua_longjmp *errorJmp; /* current error recover point */
ptrdiff_t errfunc; /* current error handling function (stack index) */
};
假设我是您的lua_State*
。如您所见,L->ci
保留当前的CallInfo,CallInfo数组包含在L->base_ci
和L->end_ci
之间。
因此,称为C函数的LUA函数位于(L->end_ci-2)
(应与(L->ci-1)
相同),其堆栈ID(Stkid)为(L->end_ci-2)->func
。我们可以通过执行类似的操作来欺骗LUA API,让您使用堆栈ID,而堆栈ID在当前调用函数以下:
StkId saved = L->base;
L->base = L->base_ci->base;
int idx = (L->end_ci-2)->func - L->base+1;
lua_getfenv(L, idx);
L->base = saved;
现在的环境表应该位于堆栈的顶部。
编辑:有效索引的LUA API检查有点棘手。这应该欺骗他们。
- 当使用Lua作为嵌入式语言(比如c++)时,有什么简单/方便的方法可以找到变量在Lua中的定义位置吗
- 如何在C++中正确设置Lua局部变量
- 通过require在不同的Lua状态之间共享全局变量
- 如何从 Lua 访问运行 Lua 脚本的类的变量
- 在C 函数中打印一个来自LUA的静态变量
- 使用LUA中使用后缺少的全局变量
- 如何在LUA C API中分配全局LUA函数变量
- 从C++调用 Python 或 Lua 来计算表达式,仅在需要时计算未知变量
- 加载 Lua 文件并使用变量而不执行函数
- 如何在不运行的情况下识别LUA脚本中的非初始化变量
- 使用Lua定义C++游戏中对象的变量
- 从C 访问功能环境中的LUA变量
- 如何从C++中过滤掉Lua中用户定义的全局变量
- 将 Lua 中的变量提取到C++中
- Lua、元表和全局变量
- c++lua设置全局变量时出错
- Lua中变量的内存RAM地址
- 将变量命名为Lua
- 在Lua中跟踪变量以进行读访问,以启动用户定义的c++方法/函数
- 如何将Lua变量直接映射到C++变量