LuaPlus:如何使函数返回一个表?

我想知道如何从 C++ 端创建和注册一个函数,在从 Lua 端调用它时返回一个表格。

我尝试了很多事情,但没有什么真正有效。:/(抱歉代码有点长)

例如,这个示例不起作用,因为 Register() 需要一个“luaCFunction”形式的函数:

LuaPlus::LuaObject Test( LuaPlus::LuaState* state ) {
    int top = state->GetTop();
    std::string var( state->ToString(1) );

    LuaPlus::LuaObject tableObj(state);
    tableObj.AssignNewTable(state);

    if (var == "aaa")
        tableObj.SetString("x", "ABC");
    else if (var == "bbb")
        tableObj.SetString("x", "DEF");
    tableObj.SetString("y", "XYZ");
    return tableObj;
}
int main()
{
    LuaPlus::LuaState* L = LuaPlus::LuaState::Create(true);
    //如果没有 true,我不能访问标准库,如“math。”,“string。”…
    //使用 true,尽管 GetLastError 返回 2(ERROR_FILE_NOT_FOUND)
    //但是没有发现任何副作用

    LuaPlus::LuaObject globals = L->GetGlobals();

    globals.Register("Test",Test);

    char pPath[MAX_PATH];
    GetCurrentDirectory(MAX_PATH,pPath);
    strcat_s(pPath,MAX_PATH,"\\test.lua");
    if(L->DoFile(pPath)) {
        if( L->GetTop() == 1 ) // An error occured
            std::cout << "An error occured: " << L->CheckString(1) << std::endl;
    }
}

当我尝试将其设置为 luaCFunction 函数时,它会崩溃(0x3)并显示:

Assertion failed: 0, file C:\......\ luafunction.h, line 41

int Test( LuaPlus::LuaState* state ) {
    int top = state->GetTop();
    std::string var( state->ToString(1) );

    LuaPlus::LuaObject tableObj(state);
    tableObj.AssignNewTable(state);

    if (var == "aaa")
        tableObj.SetString("x", "ABC");
    else if (var == "bbb")
        tableObj.SetString("x", "DEF");
    tableObj.SetString("y", "XYZ");

    tableObj.Push();

    return state->GetTop() - top;
}

为了澄清一下:从 Lua 端,我希望它被称为:

myVar = Test("aaa")
Print(myVar) -- output: ABC

编辑: Print 函数来自 这里。并且基本上导致了它无法工作。Print 只能打印字符串而不是表格……上面的 C++ 代码运行正常,如果你只返回 1。

顺便说一下,这是我的 LuaPlus 版本随附的文档:http://luaplus.funpic.de/

我真的希望你能帮助我……我已经开始认为这是不可能的了。:'(

编辑: 我完全忘记说使用 PushStack() 会导致一个“成员不存在”的错误……

点赞
用户1212870
用户1212870

首先,你可以尝试使用RegisterDirect()函数注册函数,这可能可以避免lua_CFunction的问题,查看luaplus手册,例如:

LuaPlus::LuaObject globals = L->GetGlobals();

globals.RegisterDirect("Test",Test);

第二,如果我记得要创建一个具有两个解决方案的表格,例如:

//第一种
LuaObject globalsObj = state->GetGlobals();
LuaObject myArrayOfStuffTableObj = globalsObj.CreateTable("MyArrayOfStuff");

//第二种
LuaObject aStandaloneTableObj;
aStandaloneTableObj.AssignNewTable(state);

检查是否使用了正确的函数。

第三,我记得lua堆栈对象不是luaobject,它们有一种转换方式,可以尝试这样做:

LuaStackObject stack1Obj(state, 1);
LuaObject nonStack1Obj = stack1Obj;

第四,像你上面给出的Test()函数一样,你已经把tableObj推到了lua堆栈上,你必须记住清除对象。

2013-11-13 13:08:43