gpt4 book ai didi

c - LuaJit - 从模块/包获取元表并将其分配给用户数据

转载 作者:行者123 更新时间:2023-11-30 17:29:14 24 4
gpt4 key购买 nike

假设我有一个自定义结构 vector2_t 的元表,它位于模块 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 的实例(及其关联的元表)作为参数传递给该函数。

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 的实例作为函数参数传递。我很抱歉发布了这么多代码,但我想确保我的解释正确。

最佳答案

cdata 和 userdata 是完全不同的东西。它们唯一的交互是您可以获得指向用户数据的 FFI void* 指针。值得注意的是,cdata 对象没有 C API。混合它们肯定会让你很头疼。

选择 Lua C API 或 FFI,并尽可能坚持使用。

<小时/>

直接回答您的问题:

how to pas [sic] an instance of that vector2_t as the function parameter

对于 Lua C API 函数,它像其他值一样在堆栈上传递。请注意,它将是 cdata 类型对象,而不是 userdata 对象。值得注意的是,您无法获得指向它的指针。

How do I get the meta table vector2_t on to the stack?

你不能,因为你没有让第一个脚本中的外部脚本可以访问元表。 luaL_getmetatable 仅适用于使用 luaL_newmetatable 创建的元表

关于c - LuaJit - 从模块/包获取元表并将其分配给用户数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25715722/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com