0

假设我有一个自定义结构的元表,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

在另一个脚本中,我有这个回调/事件侦听器函数,它必须接收 avector2_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作为函数参数传递。很抱歉发布了这么多代码,但我想确保我解释正确。

4

1 回答 1

0

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

选择 Lua C API 或 FFI,并尽可能坚持下去。


直接回答你的问题:

如何传递 [原文如此] 该 vector2_t 的实例作为函数参数

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

如何将元表 vector2_t 放入堆栈?

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

于 2014-09-08T13:17:38.267 回答