создание структуры обратного вызова для передачи в FFI LuaJIT

Итак, сначала я загружаю в нужную мне 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?

2

Решение

Создание 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 объект.

6

Другие решения


По вопросам рекламы [email protected]