How to get multiple returned tables from Lua function?

二次信任 提交于 2019-12-13 18:12:54

问题


I'm trying to send multiple float arrays from C++ to Lua function as arguments and then return multiple tables from the function so I can use them again as float arrays in C++.

So my Lua function will look like this.

function perform(arg1, arg2)
    local ret1, ret2 = {}, {}
    for i=1, #arg1 do
        ret1[i] = arg1[i] * 0.2;
        ret2[i] = arg2[i] * 0.3;
    end
    return ret1, ret2
end

And this is how I send and return multiple tables to/from Lua function in C++.

lua_getglobal(L, "perform");

for (int i=0; i<numArgs; ++i) {

    lua_newtable(L);
    float *in = reinterpret_cast<float*>(w[i]);

    for (int j=0; j<64; ++j) {

        lua_pushinteger(L, j+1);
        lua_pushnumber(L, in[j]);
        lua_settable(L, -3);
    }
}
lua_call(L, numArgs, numRets);

for (int i=0; i<numRets; ++i) {

    float *out = reinterpret_cast<float*>(w[numArgs+i]);

    for (int j=0; j<64; ++j) {

        lua_pushinteger(L, j+1);
        lua_gettable(L, -2);
        out[j] = lua_tonumber(L, -1);
        lua_pop(L, 1);
    }
    //how to detect next returned table?
}

But if I try the code, the returned arrays have same values.

I think it's because I'm not correctly getting the returned tables.

Could anybody please teach me how to get multiple returned tables correctly?

P.S: I would also like to know if my code can be optimized for better performance.

EDIT : Would it be faster(more efficient) to pass and return one table that has multiple sub-tables? If so, I'd appreciate if anyone can teach me how to do it.


回答1:


I have no idea what you are trying to do here, but the second table returned from the function is easily accessible on the stack. You just have to perform some arithmetic on the stack index to get to the correct position.

Those reinterpret_casts look extremely fishy to me. You are quite likely to be doing something wrong.

#include <iostream>
#include <vector>

#include <lua.hpp>

int main(int argc, char *argv[]) {
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);

    if (argc != 2) {
        std::cerr << "Usage: " << argv[0] << " <script.lua>\n";
        return 1;
    }

    luaL_dofile(L, argv[1]);

    // Mock data
    int numArgs = 2;
    int numRets = 2;
    std::vector<float> w1(64, 1.0f);
    std::vector<float> w2(64, 1.0f);
    std::vector<float> w3(64, 1.0f);
    std::vector<float> w4(64, 1.0f);
    std::vector<float *> w = {w1.data(), w2.data(), w3.data(), w4.data()};

    lua_getglobal(L, "perform");

    for (int i = 0; i < numArgs; ++i) {

        lua_newtable(L);
        float *in = reinterpret_cast<float *>(w[i]);

        for (int j = 0; j < 64; ++j) {
            lua_pushinteger(L, j + 1);
            lua_pushnumber(L, in[j]);
            lua_settable(L, -3);
        }
    }

    lua_call(L, numArgs, numRets);

    for (int i = 0; i < numRets; ++i) {

        float *out = reinterpret_cast<float *>(w[numArgs + i]);

        for (int j = 0; j < 64; ++j) {
            lua_pushinteger(L, j + 1);
            lua_gettable(L, -2 - i); // Just some stack index arithmetic
            out[j] = lua_tonumber(L, -1);
            lua_pop(L, 1);
        }
    }

    lua_close(L);
}


来源:https://stackoverflow.com/questions/50854346/how-to-get-multiple-returned-tables-from-lua-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!