c++ - 如何在与 LUA 脚本一起使用的 lambda 中引用“this”
问题描述
我正在尝试将 LUA API 添加到我的 C++ 程序中,并且我正在尝试允许脚本绘制到我的 GUI。到目前为止,我的 lambda 函数有这个:
auto addToDrawList = [](lua_State* L) -> int
{
int DrawType = (int)lua_tonumber(L, -2);
std::string Label = (std::string)lua_tostring(L, -1);
bool found = false;
for (int i = 0; i <= DrawList.size(); i++)
{
if (DrawList[i].Active == false && !found)
{
switch (DrawType)
{
case(0):
break;
case(1):
DrawList[i].Active = true;
DrawList[i].DrawType = Type::TextBox;
DrawList[i].Label = Label;
break;
}
found = true;
}
}
return 0;
};
这是我正在运行的 LUA 脚本:
const char* LUA_FILE = R"(
addToDrawList(1, "Test")
)";
这就是我将函数推送到 LUA 堆栈的方式:
lua_State* L = luaL_newstate();
lua_newtable(L);
int uiTableInd = lua_gettop(L);
lua_pushvalue(L, uiTableInd);
lua_setglobal(L, "Ui");
lua_pushcfunction(L, addToDrawList);
lua_setfield(L, -2, "addToDrawList");
问题出在我的第一个脚本中,因为它无法将 'DrawList' 数组作为this
.
因此,为了解决它,我尝试this
通过执行以下操作添加到 lambda 的捕获列表中:
auto addToDrawList = [this](lua_State* L) -> int
这似乎可以工作并解决错误,但后来我遇到了最后一个脚本的问题:
lua_pushcfunction(L, addToDrawList);
我一直在 Internet 上搜索修复程序,但找不到任何解决方法。
解决方案
lua_pushcfunction()
采用 C 风格的函数指针。无捕获的lambda 可以转换为这样的函数指针,但捕获的lambda 不能。
请改用1。它将允许您将用户定义的值(称为upvalues)与 C 函数相关联,例如您的指针,或者只是指向 的指针等。lua_pushcclosure()
this
DrawList
创建 C 函数时,可以将一些值与其关联,从而创建 C 闭包(参见§3.4);然后,无论何时调用该函数,都可以访问这些值。要将值与 C 函数关联,首先应将这些值压入堆栈(当有多个值时,首先压入第一个值)。然后
lua_pushcclosure
调用创建 C 函数并将其压入堆栈,参数n
告诉函数应该与多少值相关联。lua_pushcclosure
还会从堆栈中弹出这些值。
1:lua_pushcfunction()
只是lua_pushcclosure()
定义了 0 个上值的包装器。
例如:
auto addToDrawList = [](lua_State* L) -> int
{
const MyClassType *pThis = (const MyClassType*) lua_topointer(L, lua_upvalueindex(1));
// use pThis->DrawList as needed...
return 0;
};
...
lua_State* L = luaL_newstate();
...
//lua_pushcfunction(L, addToDrawList);
lua_pushlightuserdata(L, this);
lua_pushcclosure(L, addToDrawList, 1);
...
推荐阅读
- javascript - 自定义 Javascript 变量在历史更改时返回不同的值
- python - 在 Python Pandas 中对行(日期)进行分组并汇总多个列(每个日期的几个测量值)
- c++ - boost::spirit::x3 phrase_parse 在推入向量之前进行算术运算
- unit-testing - 如何在 Rust 中断言 io 错误?
- asp.net-core - 具有多个注册的 IAuthorizationHandler - 依赖解析器如何选择正确的实现?
- api - 如何在烧瓶 api 服务 (SPA) 中信任 azure 活动目录不记名令牌
- android - 如何在 Android Studio 中创建带有渐变动画的三星“立即修复”按钮
- c# - 为什么 Unity (DI) 可以在 Controller 中工作,而不能在我的服务层中工作?
- reactjs - 如何使用 webpack 在 React 中创建 Bundle
- python - paramiko.SSHClient.exec_command 挂起