Я пытаюсь отправить несколько массивов с плавающей запятой из C++ в функцию Lua в качестве аргументов, а затем вернуть несколько таблиц из функции, чтобы я мог снова использовать их как массивы с плавающей запятой в C++.
Итак, моя функция Lua будет выглядеть так.
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
И вот как я отправляю и возвращаю несколько таблиц в / из функции Lua в 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?
}
Но если я попробую код, возвращенные массивы будут иметь те же значения.
Я думаю, это потому, что я неправильно получаю возвращенные таблицы.
Может ли кто-нибудь научить меня, как правильно получить несколько возвращаемых таблиц?
P.S: Я также хотел бы знать, можно ли оптимизировать мой код для повышения производительности.
Обновлено: Было бы быстрее (эффективнее) передать и вернуть одну таблицу с несколькими вложенными таблицами? Если так, я был бы признателен, если бы кто-нибудь научил меня, как это делать.
@Clonk Было бы быстрее передать одну таблицу с двумя подтаблицами? а также, было бы быстрее вернуть одну таблицу с двумя подтаблицами?





Я понятия не имею, что вы здесь пытаетесь сделать, но вторая таблица, возвращаемая функцией, легко доступна в стеке. Вам просто нужно выполнить некоторые арифметические действия с индексом стека, чтобы добраться до правильной позиции.
Эти reinterpret_casts мне кажутся очень подозрительными. Вы, скорее всего, делаете что-то не так.
#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);
}
Большое спасибо! Теперь это работает. Но мне пришлось установить индекс стека как -numRets-1 + i вместо -2 - i, чтобы соответствовать arg1=ret1, arg2=ret2. И reinterpret_cast использовался, потому что w относится к типу long *. (Для хранения любых указателей)
Не могли бы вы ответить на вопрос, который я написал в конце своего сообщения?
Я не думаю, что использование подтаблиц будет быстрее, но вам понадобится значительно больше шаблонов на стороне C++. Однако единственный способ узнать наверняка - это провести сравнительный анализ.
Вы имеете в виду, что мне понадобится значительно больше шаблонов на стороне C++, если я буду использовать подтаблицы, верно? Тогда я буду придерживаться текущего дизайна. :) Большое спасибо!
@ZackLee Да, вам понадобится больше шаблонов в C++, потому что вам нужно сначала проиндексировать родительскую таблицу, прежде чем вы сможете индексировать подтаблицы, что требует дополнительного цикла и дополнительного lua_gettable. В текущих решениях две таблицы уже находятся в стеке и готовы к просмотру.
Спасибо за ваш ответ. :)
почему есть 2 стола? Почему нет одной таблицы с двумя элементами для каждой записи?