Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/Neopallium/LuaNativeObjects

A Lua bindings generator written in Lua.
https://github.com/Neopallium/LuaNativeObjects

Last synced: about 2 months ago
JSON representation

A Lua bindings generator written in Lua.

Awesome Lists containing this project

README

        

LuaNativeObjects
================

This is a bindings generator for Lua & LuaJIT2. It can be used to generator both standard Lua C API & LuaJIT2 FFI based bindings for C libraries. Both standard & FFI based bindings are packaged in a single shared library (.so or .dll) file. When the module is loaded in LuaJIT2 (please use git HEAD version of LuaJIT2 for now) it will try to load the FFI-based bindings in-place of the standard Lua API bindings.

This bindings generator is design to create Object based bindings, instead of simple procedural bindings. So if you have a C structure (your object) and a set of C functions (your object's methods) that work on that structure, then you can turn them into a nice Lua object.

It is still possible to generator procedural bindings for C functions that don't belong to an object (use a `package` record instead of an `object` record).

Lua bindings using this generator
---------------------------------

* [Lua-zmq](http://github.com/Neopallium/lua-zmq)
* [Luagit2](http://github.com/Neopallium/luagit2)

Template project for starting new bindings
------------------------------------------

There is a template for creating a new bindings project. This is a lua script for automatically creating a new project from the template.

To start a new bindings project run:

$ cd LuaNativeObjects/project_template/
$ lua RUN_THIS_FIRST.lua

Then answer the questions and it will setup the new project.

Example bindings
----------------

This example bindings code is take from the 'examples' folder.

-- define the 'gd' module
c_module "gd" {
-- when set to true all objects will be registered as a global for easy access.
use_globals = true,

-- enable FFI bindings support.
luajit_ffi = true,

-- load GD shared library.
ffi_load"gd",

-- include library's header file
include "gd.h",

object "gdImage" {
-- Use `ffi_cdef` records to pass extra C type info to FFI.
ffi_cdef[[
typedef struct gdImageStruct gdImage;
]],
-- The first constructor can be called as: gd.gdImage(x,y) or gd.gdImage.new(x,y)
-- The default name for a constructor is 'new'
constructor {
c_call "gdImage *" "gdImageCreate" { "int", "sx", "int", "sy" }
},
-- Other constructors can be called by there name: gd.gdImage.newTrueColor(x,y)
constructor "newTrueColor" {
c_call "gdImage *" "gdImageCreateTrueColor" { "int", "sx", "int", "sy" }
},
-- A named destructor allows freeing of the object before it gets GC'ed.
destructor "close" {
c_method_call "void" "gdImageDestroy" {}
},

method "color_allocate" {
-- bindings for simple methods/functions can be generated with `c_method_call` or `c_call`
-- records, which will generate both Lua API & FFI based bindings for the function.
c_method_call "int" "gdImageColorAllocate"
{ "int", "r", "int", "g", "int", "b" }
},

method "line" {
c_method_call "void" "gdImageLine"
{ "int", "x1", "int", "y1", "int", "x2", "int", "y2", "int", "colour" }
},

-- The next method need extra FFI types & function information.
ffi_cdef[[
/* dummy typedef for "FILE" */
typedef struct FILE FILE;

FILE *fopen(const char *path, const char *mode);
int fclose(FILE *fp);

void gdImagePng(gdImage *im, FILE *out);
]],
-- This method is more complex and can't be generated with a simple `c_method_call` record.
method "toPNG" {
-- Use `var_in`/`var_out` records to define parameters & return values.
var_in { "const char *", "name" },
-- Use `c_source` records to provide the C code for this method.
c_source [[
FILE *pngout = fopen( ${name}, "wb");
gdImagePng(${this}, pngout);
fclose(pngout);
]],
-- if you want this method to have FFI-based bindings you will need to use a `ffi_source` record
ffi_source [[
local pngout = ffi.C.fopen(${name}, "wb")
C.gdImagePng(${this}, pngout)
ffi.C.fclose(pngout)
]]
},
}
}

Marking input & output variables
--------------------------------

The `c_call` & `c_method_call` records have support for annotating the return type and function parameters to control how the generated bindings work.

c_call "int>1" "func_name"
{ "ObjectType1", "&need_pointer_to_pointer_is_out_var_idx2>2", "ClassObject", "this<1" }

`idx`, mark as an output that will be returned from the function back to Lua. The `idx` value controls the order of output values as returned to Lua.

`!`, mark will cause owner-ship of an object to transfer between C & Lua.
For output variables Lua will take owner-ship the object instance and free it when the object's `__gc` is called.
For input variables Lua will give-up owner-ship of the object and only keep a reference to the object.

`#var`, reference the length of the named variable `var`. This is used for 'string' type input parameters.

`?`, mark the input parameter as optional.

`&`, this will wrap the variable access with `&(var)` to pass a pointer to the value. This is needed for some C functions that have output parameters.

`*`, this will wrap the variable access with `*(var)` to de-reference a pointer and pass it by-value.