使用 Lua FFI 处理复杂类型

有一个稍微复杂一些的用例……试图通过 C 包装器从 Lua FFI 访问 C++ 对象。

ffi.load("wrapper.so")
​
ffi.cdef[[
struct puppy;
typedef struct puppy puppy_t;
puppy_t *   puppy_bark     (const char *encoded);
]]

然而,每次我尝试实例化小狗时,它都会返回“C 类型的大小未知或太大”。

我已经尝试了以下内容来创建小狗...

pup = ffi.typeof("puppy_t")
pup.puppy_bark("some text")

结果是结构体“puppy”没有名为“puppy_bark”的成员。

pup = ffi.new("struct puppy_t")
pup.puppy_bark("some text")

返回“未声明或隐式标记”。

pup = ffi.new("struct puppy puppy_t")
pup.puppy_bark("some stringish thing")

返回“期望 ' ' 附近的小狗”。

假设 C 包装器正确地具有小狗结构、类型和必需的方法,如何创建小狗的实例或指针,以便让它叫?

提前致谢!

点赞
用户106104
用户106104

你问:“我如何创建一个小狗的实例或指针,以使它叫?” - 但是在没有定义的情况下是不可能创建某个东西的实例的,也不可能在没有实例的情况下创建其指针,且你的代码不能使小狗叫(但是有一个全局函数“puppy_bark”可以创建一个新小狗?)。

看起来你可以通过调用puppy_bark来创建一个小狗(即使这个函数名非常恶劣),但是我不能确定在puppy_bark的实际代码中是否是这样的。

既然我没有特定问题的具体答案,这里有一些可能会对你有所帮助的事情:

  1. ffi.new("puppy_t")不起作用,因为FFI需要有struct puppy定义,而不只是前向声明,出于正好与这种情况在C++中不能这样的原因。

    struct puppy;
    puppy *p = new puppy;
    

    因此,如果你想这样做,你需要将完整的定义加载到FFI中。注意,LuaJIT的FFI只支持C代码,而不支持C++。

  2. ffi.new("struct puppy_t")不起作用,因为那不是存在的类型。

  3. ffi.new("struct puppy puppy_t")不起作用,因为那不是一个有效类型。

  4. pup = ffi.typeof("puppy_t")   pup.puppy_bark("some text")不起作用,因为puppy_bark不是struct puppy的成员(正如错误消息所告诉你)。

    看起来你也误解了ffi.typeof的目的。根据文档,ffi.typeof返回给定类型的构造函数,所以:

    local new_puppy = ffi.typeof("puppy_t")
    local puppy = new_puppy(1, 2, 3, 4)
    

    等同于

    local puppy = ffi.new("puppy_t", 1, 2, 3, 4)
    

    如果您想调用全局函数puppy_bark,可以使用ffi.C.puppy_bark("some text")

2015-12-21 23:49:21