假设我有一个自定义结构vector2_t
的metatable,它位于模块 mymod 中,如下所示:
local mymod = {}
local ffi = require("ffi")
local C = ffi.C
ffi.cdef[[
typedef struct
{
double x;
double y;
} vector2_t;
]]
local vector2_t
vector2_t = ffi.metatype("vector2_t", {
__eq = function(lhs, rhs)
if lhs.x == rhs.x and lhs.y == rhs.y
then return true else return false end
end
-- Member functions follow...
})
vcmp.vector2 = vector2_t
-- I use this method because the script is integrated in C/C++ as a string and not
-- as a file and I need a constant name that isn't decided by the file name
package.preload["mymod"] = function(mod) return mymod end
在另一个脚本中,我有这个回调/事件监听器函数,它必须接收vector2_t
作为它的参数:
local mymod = require "mymod"
local some_pos = mymod.vector2(32, 29.7)
-- That pos argument must be an instance of mymod.vector2_t
function position_update(pos)
print("New Pos: " .. pos.x .. ", " .. pos.y .. "\n")
some_pos.x = pos.x
some_pos.y = pos.y
end
现在,我必须从C / C ++调用该回调/事件监听器函数,并将该vector2_t
的实例(以及它的关联metatable)作为该函数的参数传递。
typedef struct
{
double x;
double y;
} vector2_t;
void call_position_update(lua_State* L, double x, double y)
{
// Retrieve the function
lua_getglobal(L, "position_update");
// Validate it
if (!lua_isfunction(L, lua_gettop(L)))
{
lua_pop(L, 1);
return;
}
// Create an instance of vector2_t
vector2_t *pos = (vector2_t *)lua_newuserdata(L, sizeof(vector2_t));
// Assign the values to the new instance
pos->x = x;
pos->y = y;
// How do I get the meta table vector2_t on to the stack?
// Reach to the module somehow...
// Get the meta table from the module
luaL_getmetatable(L, "vector2_t");
// Assign the meta table to the vector2_t instance already on the stack
lua_setmetatable(L, -2);
// I'm assuming that the vector2_t instance is already on the stack so there's nothing else to push
// Call the function with 1 argument which should be that vector2_t onto the stack
if (!lua_pcall(L, 1, 0, 0))
{
printf("Error calling function 'position_update': %s\n", lua_tostring(_Lua, -1));
}
}
我有点迷失,我不知道如何将vector2_t
的实例作为函数参数。我很抱歉发布了这么多代码,我想确保我的解释正确。
答案 0 :(得分:0)
cdata和userdata完全不同。他们唯一的互动是你可以得到一个指向userdata的FFI void*
指针。值得注意的是,cdata对象没有C API。混合它们肯定会引起很多麻烦。
选择Lua C API或FFI,并尽可能坚持下去。
直接回答你的问题:
如何将该vector2_t的实例作为函数参数
进行传递
对于Lua C API函数,它会像其他值一样在堆栈上传递。请注意,它将是cdata类型的对象,而不是userdata对象。值得注意的是,你无法获得指向它的指针。
如何将元表vector2_t放到堆栈上?
您不能,因为您不能在第一个脚本中使外部脚本可以访问元表。 luaL_getmetatable
仅适用于使用luaL_newmetatable