FFI is cool and it is very fast - C fast. But it is also has a bunch of baggage. Here’s some quick tips and code snippets using ffi, and how you can leverage it.
The Bad
FFI bypasses the normal C calling convention in Lua to call C methods. This means when you call an FFI C method you can jump into handling pointers and addresses directly. This means crashing your application (and even Defold) is a real possibility. Beware!
FFI is platform specific. When you call into the lower levels, you are calling that platforms specific methods that are compiled for that platform (OS/Hardware). This means if you need cross platform you will need to make FFI mappings for each.
Note: FFI will not work on html5 (or I dont think it will - wasm might blow up). FFI should work on the other target platforms though.
The Good
Because FFI lets you call native C methods it is insanely quick. And the Luajit system treats it like directly calling a C function. This means you get the great benefits of the jit prediction systems and the speed of running something at maximum perf on a machine.
It is horribly easy to use. One of the best ways to be able to interface with Lua and very easy to write for - just write a C dll/so and call it
How?
This all sounds interesting Dave, what is it, and how can I use it.
Heres a quick example. We want to call the OS level malloc to make a huge amount of memory (which we cant always do in Lua), and we want to put stuff in it.
local ffi = package.preload.ffi() -- In Defold this is a little different. Normaly you use: local ffi = require("ffi")
-- Define the methods you want to use (these are OS methods)
ffi.cdef[[
void * malloc( size_t bytes );
void free(void *ptr);
]]
-- Thats it. We are done! Now we can call malloc and free directly!!
local mymem = ffi.C.malloc( 1e8 ) -- alloc 100MB - you can make this over 2GB which is lua's own internal limit
-- Put something in it. FFI lets you use 0 based array assignment!
mymem[0] = 10
mymem[100000] = 20
-- Get the values
pprint(mymem[0], mymem[100000])
-- Let the memory free! Do not forget to do this, or you may end up in a bit of a mess
ffi.C.free(mymem)
Some things to note.
When using C library methods like malloc and free, ffi maps them into the ffi.C object. This is why you call them with a leading ffi.C.
When loading external libraries you need to call ffi.load on the library, which will make the methods in for you . More details here: FFI Library