2

所以首先我加载我需要的 DLL

local ffi = require("ffi")
local theDLL = ffi.load("thisDLL")

在 ffi cdef 我有两种不同的结构

ffi.cdef [[
    typedef struct StructSession StructSession;
    typedef struct {
        /*
        * begin_proj callback
        */
        bool (__cdecl *begin_proj)(char *proj);

        /*
        * save_proj_state
        */
        bool (__cdecl *save_proj_state)(unsigned char **buffer, int *len);
    } StructCallbacks;

我在cdef中也有这个功能

__declspec(dllexport) int __cdecl start_session(StructSession **session,
                                                           StructCallbacks *cb);

现在我想调用这个函数

print(theDLL.start_session(a,b))

vars a 和 b 显然是占位符,问题是我怎样才能传递函数需要的结构?假设我们让 StructSession 正常工作,是否对 StructCallbacks 内的函数进行回调甚至是可能的?

4

1 回答 1

7

创建StructCallbacks很容易;您可以创建它ffi.new并为字段创建 FFI 回调(有关回调的信息,请参阅FFI 语义)。

由于它是不透明类型,因此创建StructSession它比较棘手,但它与您在 C 中的操作方式并没有太大区别。

下面是如何在 C 中创建一个:

StructSession* S = NULL;
start_session(*S, foo);

请注意您如何不直接分配StructSession. 相反,您分配一个指向 1 的指针,然后start_session分配实际的结构。

所以我们现在把它翻译成 LuaJIT 代码:

local S = ffi.new("StructSession*")
lib.start_session(getPointer(S), foo) -- getPointer should take the pointer of S, but...

... FFI 没有提供任何获取对象指针的方法(这是有意的;它允许优化)。

那么我们如何获得指向 a 的指针StructSession呢?好吧,回想一下,数组可以转换为指针,我们可以通过 FFI 访问它们。所以我们改为创建一个单槽指针数组并将其传递给start_session

local S_slot = ffi.new("StructSession*[1]")
lib.start_session(S_slot, foo)
local S = S_slot[0]

现在你有了一个StructSession对象。

于 2014-05-31T15:57:03.013 回答