imagine.ffi

Description

imagine.ffi is a foreign function interface based on libffi. It's a binding between Lua 5.1+ and libffi, allowing the user to interact with any other system from Lua. You can use the imagine.ffi module to call DLL's, but also to allow other API's to call your own code through trampoline functions.

Downloads for version 1.0.2 (latest)

Changelog »

Windows

irsdk2

irsdk3

lua5.1

lua5.3

Foreign Function Interface

In essence, imagine.ffi is a foreign function interface between Lua and any other environment supported. This means that you can use this library to interact with other parts of the system you're working on. It allows you to load libraries, import functions from those libraries and invoke them with the proper function signatures.

Bi-directional

This library works in two directions:

  • From Lua to a foreign function interface;
  • From a foreign function interface to Lua.

The first direction is implemented simply by allowing you as programmer to import functions from libraries, describing them in the way they should be invoked and then you simply invoke them as if they were regular Lua functions. imagine.ffi takes care of translating your function arguments and return values for you.

The second direction allows you to have a regular Lua function and pass it to an external API. In the documentation you can read more about these prototypes. These function will function like any C/C++ compiled function to the API you're working with, but to you they are just regular old Lua functions.

Calling Conventions

Most known calling conventions are supported for the platform you download this library for. It's worth noting that the supported calling conventions differ between architectures, so be sure to read the documentation linked above to see which conventions to use for each platform. The documentation is very rich with examples.

Parameter Types

In order to call a function you can describe the parameter (and return) types of a function to match its signature precisely. All native parameter types are supported in signed and unsigned forms, floating point numbers and doubles, strings and UTF8, UTF16 and UTF32 strings are supported as well. Please note that no string conversion will be done, the encoding is only used to determine parameter length.

Memory Management

For some foreign API's you'll need memory management. I.e. you'll need to be able to work with pointers, allocate buffers, interpret structures and more. For this, we have a separate library called imagine.memory which is supported on the same platforms as this library.

local ffi = require "imagine.ffi"; -- no need for this if you use the ImagineFFI AMS Plugin

local user32 = ffi.library(_SystemFolder.."\\User32.dll") : as "user32" {
    ffi.import "MessageBoxA" 
        : as "MessageBox" 
        : convention(ffi.stdcall_abi) 
        : returns(ffi.int32_p) (ffi.pointer_p --[[hHwnd]], ffi.cstr_p --[[Text]], ffi.cstr_p --[[Caption]], ffi.uint32_p --[[Flags]]);
    
    ffi.import "EnumWindows"
        : convention(ffi.stdcall_abi)
        : returns(ffi.uint32_p) (ffi.pointer_p --[[lpEnumFunc]], ffi.pointer_p --[[lParam]]);
};

local enum_windows_proc = ffi.prototype "enum_windows_proc" 
    : convention(ffi.stdcall_abi) 
    : returns(ffi.uint32_p) (ffi.pointer_p --[[hWnd]], ffi.pointer_p --[[lParam]]);
    
local callback = enum_windows_proc(function(hWnd, lParam)
    print(hWnd);
    return true; -- will automagically be casted to uint32_p
end);

user32.MessageBox(Application.GetWndHandle(), "Hello World!!", "Caption!", 0);
user32.EnumWindows(callback:get(), 0);

Older Versions

There are multiple versions for this product. Older versions might be useful in the case of compatibility issues, but please do note that these versions are not supported anymore. The documentation for this product might also have been updated, we do not host the documentation for older versions.