2

まず、必要な DLL をロードします。

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

ffi cdefには、2種類の構造体があります

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 が機能するようになったとします。LuaJIT 内の関数へのコールバックを StructCallbacks で行うことさえ可能でしょうか?

4

1 に答える 1

7

の作成StructCallbacksは簡単です。ffi.newで作成し、フィールドの FFI コールバックを作成できます (コールバックの詳細については、 FFI セマンティクスを参照してください)。

を作成するのStructSessionは不透明な型なのでややこしいですが、C で行う方法と大差ありません。

Cで作成する方法は次のとおりです。

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

を直接割り当てていないことに注意してくださいStructSessionstart_session代わりに、ポインターを 1 つに割り当て、実際の構造体を割り当てさせます。

そこで、これを LuaJIT コードに変換します。

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

... FFI は、オブジェクトのポインターを取得する方法を提供しません (これは意図的なものであり、最適化を可能にします)。

では、へのポインターを取得するにはどうすればよい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 に答える