我正在绘制一个小型 C++ 程序,它将数组传递给 Lua 并在那里对其进行修改,我打算在程序中读取一个 lua 脚本,这样我就可以修改它而无需重新编译程序
我的第一个障碍是确保 Lua 能够修改已经分配的数组,而不是让它们在 Lua 空间中再次分配。数据将是 float 的,大小会非常大,但我现在开始很小。
为了简化这个界面,我尝试了 LuaBridge 2.6,但它没有提供预期的结果。下面是一个完全“工作”的程序。
#include <iostream>
#include <cstdint>
#include <cstring>
#include <vector>
#include <lua5.3/lua.hpp>
#include <LuaBridge/LuaBridge.h>
int main(void)
{
const uint32_t LENGTH = 512 * 256;
std::vector <float> input(LENGTH),
output(LENGTH);
memset(output.data(), 0, LENGTH * sizeof(float)); // Zero the output
for(uint32_t i = 0; i < LENGTH; i++) // Populate input
input[i] = (float)i + 0.5f;
lua_State *luastate = luaL_newstate();
luabridge::push(luastate, input.data()); // Supposedly passing a pointer to the first element of input, according to LuaBridge manual chap 3-3.1
luabridge::push(luastate, output.data()); // Same for output
luaL_dostring(luastate, "output[10] = input[256]"); // Expecting to assign this value in the C++ arrays, not in the Lua space
lua_getglobal(luastate, "output[10]"); // Find this assigned value in the Lua stack
lua_Number val = lua_tonumber(luastate, 1); // Retrieving this value from Lua to C++
std::cout << input[256] << ", " << output[10] << ", " << val << std::endl; // The values of val and in output[10] don't match
lua_close(luastate);
return 0;
}
请注意,没有任何匹配项。 Lua 中的 output[10] 不是 C++ 空间中 input[256] 的值,而是 input[0]。C++ 输出数组没有从 Lua 内部更新,cout 显示它保持我们初始化的状态 (0)。
为了确认这一点,我们将 output[10] 的这个值推送到堆栈中,它不是 C++ 中的 input[256],而是从 C++ 中检索的。
你们能纠正我或指出我应该在哪里实现这一目标吗?
======= 2020 年 8 月 11 日更新 =======
为了澄清程序正在做什么(或应该做什么),在阅读了 Robert 和 Joseph 的考虑之后,我在下面发布了 C++ 部分和它调用的 lua 脚本的更新版本。请注意,我放弃了 LuaBridge,因为我在第一次尝试中没有成功:
C++:
#include <iostream>
#include <cstdint>
#include <cstring>
#include <vector>
#include <luajit-2.0/lua.hpp> // LuaJIT 2.0.4 from Ubuntu 16.04
int main(void)
{
const uint32_t LENGTH = 256 * 512;
std::vector <float> input(LENGTH),
output(LENGTH);
memset(output.data(), 0, LENGTH * sizeof(float));
for(uint32_t i = 0; i < LENGTH; i++)
input[i] = (float)i + 0.5f;
lua_State *luastate = luaL_newstate();
luaL_openlibs(luastate);
// Here I have to pass &input[0], &output[0] and LENGTH
// to Lua, which in turn will pass to whatever functions
// are being called from a .so lib opened in Lua-side
luaL_dofile(luastate, "my_script.lua");
lua_close(luastate);
return 0;
}
Lua 脚本如下所示:local ffi = require("ffi")
local mylib = ffi.load("/path_to_lib/mylib.so")
-- Here I import and call any fuctions needed from mylib.so
-- without needing to recompile anything, just change this script
-- At this point the script has to know &input[0], &output[0] and LENGTH
ffi.cdef[[int func1(const float *in, float *out, const uint32_t LEN);]]
ffi.cdef[[int func2(const float *in, float *out, const uint32_t LEN);]]
ffi.cdef[[int funcX(const float *in, float *out, const uint32_t LEN);]]
if(mylib.func1(input, output, LENGTH) == 0) then
print("Func1 ran successfuly.")
else
print("Func1 failed.")
end
最佳答案
I am sketching a small C++ program that will pass arrays to Lua
The data will be float and the size will be really large,
我的建议:
GetTableValue(Index)
SetTableValue(Index, Value)
它应该是这样的:
static int LUA_GetTableValue (lua_State *LuaState)
{
float Value;
/* lua_gettop returns the number of arguments */
if ((lua_gettop(LuaState) == 1) && (lua_isinteger(LuaState, -1)))
{
/* Get event string to execute (first parameter) */
Offset = lua_tointeger(LuaState, -1);
/* Get table value */
Value = LUA_FloatTable[Offset];
/* Push result to the stack */
lua_pushnumber(Value);
}
else
{
lua_pushnil(LuaState);
}
/* return 1 value */
return 1;
}
您还需要注册该功能:lua_register(LuaState, "GetTableValue", LUA_GetTableValue);
我让你写SetTableValue
但它应该非常接近。这样做,缓冲区在 C 端,可以从
Lua
访问。具有专用功能。
关于c++ - 从 Lua 修改 main() 中的 C++ 数组,无需额外分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64707309/