我正在绘制一个小型 C++ 程序,它将数组传递给 Lua 并在那里修改它们,我打算在程序中读取一个 lua 脚本,这样我就可以修改它而无需重新编译程序
我的第一个障碍是确保 Lua 能够修改已经分配的数组,而不是让它们在 Lua 空间中再次分配。数据将是浮动的,大小会非常大,但我现在开始很小。
为了简化这个界面,我尝试了 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