Examples

Examples:

Calling virtual functions

-- Get the interface address
local IVEngineClient = utils.find_interface("engine.dll", "VEngineClient014") or error("Engine client is invalid")

-- Cast to a pointer that can be dereferenced
local IVEngineClientPtr = ffi.cast("void***", IVEngineClient)

-- Dereference to get the vtable 
local IVEngineClientVtable = IVEngineClientPtr[0]

-- Get virtual function ptr
local ClientCmdPtr = IVEngineClientVtable[108]

-- Cast the address to the function type
local ClientCmd = ffi.cast(ffi.typeof("void(__thiscall*)(void*, const char*)"), ClientCmdPtr)

-- Call the virtual function with the interface ptr as the first argument
ClientCmd(IVEngineClientPtr, "say Hello from lua-ffi")

-------------------------------------------------
-- All of this can be compacted into one function
-------------------------------------------------

local function vtable_bind(interface, type, index)
    local this = ffi.cast("void***", interface)
    return function (...)
        return ffi.cast(ffi.typeof(type), this[0][index])(this, ...)
    end
end
--                                       Interface       Function type                            Virtual index
local ClientCmd_AltVersion = vtable_bind(IVEngineClient, "void(__thiscall*)(void*, const char*)", 108)

Watermark

Accessing callbacks

Last updated