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.
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);
}