Итак, сначала я загружаю в нужную мне DLL
local ffi = require("ffi")
local theDLL = ffi.load("thisDLL")
У меня есть два разных вида структур.
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))
переменные a и b, очевидно, являются заполнителями, вопрос в том, как я могу передать структуры, необходимые для функции? И, скажем, у нас работает StructSession, возможно ли сделать возможным обратный вызов функции WITHIN LuaJIT для StructCallbacks?
Создание StructCallbacks
это просто; Вы можете создать его с ffi.new
и создать обратные вызовы FFI для полей (см. Семантика FFI для получения информации о обратных вызовах).
Создание StructSession
сложнее, так как это непрозрачный тип, но он не сильно отличается от того, как вы сделали бы это в C.
Вот как вы могли бы создать один в C:
StructSession* S = NULL;
start_session(*S, foo);
Обратите внимание, что вы не выделяете StructSession
, Вместо этого вы выделяете указатель на один и позволяете start_session
выделить фактическую структуру.
Итак, теперь мы переведем это в код 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
объект.