Checked 16-Jul-03 for v.2.17d
Added callbacks 23-Sep-03 (v.2.19c)


GluaX Programmer's Manual


GluaX is based on 'glua10' (Glua 1.0) by Enrico Colombini.

In addition to this document (which tries to be brief) you should also read release notes and some sample code.

If you find any inconsistencies or mistakes in this documentation, please report them to:

- asko.kauppi@sci.fi


Module Initialisation

GluaX code can be compiled into both dynamically linked extension modules (dll's on Win32, so's in Linux) as well as normal statically linked Lua/C applications. The entry points (and of course the compiler settings) for these two linkage differ, but otherwise the GluaX code is the same, no matter which way you prefer. You can even link the same source code both dynamically and statically.

Module block

Each GluaX module has a module block which serves as the entry point for initialising the module with Lua. This block is called automatically by the host application when the module is being linked to.

Here is a simple module block, registering one C function:

    GLUA_MODULE( my_path, my_tbl )
    {
        GLUA_DECL( my_tbl )
            {
            glua_func( HelloFunc )
            }
        GLUA_DECL_END
    }
    GLUA_MODULE_END

'My_path' and 'my_tbl' are names of regular C variables (of type const char* and int) that you may use if you like.

'My_path' is the path (including filename) of your extension module and may be used for reading configuration files etc. 'My_tbl' is the Lua namespace table that the host (or the end user) has chosen for you. This helps keep the global namespace unpolluted, especially if there are multiple extension modules at work.

Note that you cannot know the name of that namespace even if you wanted to. This is done by purpose to let the scripts freely decide on namespaces, without the need to recompile any modules. You can force definitions to go global (ignoring the proposed namespace) by passing 0 to 'GLUA_DECL'. Use this only if you really need to since it reduces the reusability and versatility of your module.

Declaration block

Any C functions or constants we want Lua to be able to 'see' need to be declared to it at runtime. That is the purpose of the 'GLUA_DECL' block. Within that block, you can have any number of the following macros, in any order(*):

    glua_func( func )
    glua_func2( lua_name, func )
    glua_const( num_constant )
    glua_const2( lua_name, num_value )
    glua_str( str_var )
    glua_str2( lua_name, str_value )
    glua_tag( name, tag_ref )
    glua_tagmethod( tag, event_name, func )

(*) Note: 'glua_tagmethod' entries need to come after the corresponding 'glua_tag' entries that initialize the tag values.

There may be several 'GLUA_DECL' blocks, e.g. if you want some of your declarations to be global.


Interface functions

Parameters are passed between Lua and C via a typeless stack. This allows for much more versatility than the normal C parameter passing (well, which also uses a stack, but it's ...er... a different kind of stack ;). Anyways, you can pass integers, strings, tables, also return multiple values (which is not possible in C) and so forth. The GluaX macros do error checking for you (required in a typeless environment such as Lua). Next, we'll look into these macros in more detail.

Function block

The functions declared within the 'GLUA_DECL' block must have a "body" somewhere. This body is enclosed within 'GLUA_FUNC' macros and may look like this:

    GLUA_FUNC( BitAnd )
    {
    int a,b;

        a = glua_getInteger(1);
        b = glua_getInteger(2);

        glua_pushInteger( a & b );  // Bitwise AND
    }
    GLUA_END

This code needs to be in the same source file as the 'GLUA_DECL' block and before it (in order to be visible for the declaration). The name 'BitAnd' is not the real C function name but an id used by GluaX. This allows using the exact same name here as with an existing C function, without collisions.

Note: you can use 'break' anywhere within the GLUA_FUNC block to do an "early escape" if you need to. Do not use 'return'.

Getting arguments from Lua

The following macros are usable within a 'GLUA_FUNC' block to read function arguments into C. Reading a value does not remove it from the stack and the values may be read in any order, even though 1..N is usual (as seen in the sample above).

    double      glua_getNumber(argn)
    int         glua_getInteger(argn)
    const char* glua_getString(argn)
    const char* glua_getLString(argn, len_ref)
    const void* glua_getUserdata(argn, tag)
    bool_int    glua_getBoolean(argn)
    void        glua_getTable(argn)

The last function 'getTable()' "opens" a parameter table for closer access by the following functions:

    int         glua_getTable_int(key)
    double      glua_getTable_num(key)
    const char* glua_getTable_str(key)
    void*       glua_getTable_ud(key,tag)
    bool_int    glua_getTable_bool(key)

These functions take a text 'key' as their parameter. This key can include subtable access using "dot notation" (e.g. 'obj.color.red') to dive into tables. In C++ the keys can also be integers, integer pairs and combinations of integer + subtable key. See header files for more information.

Also browsing through all the table items is possible with the following construct (see 'sample.c' for the full code):

    const char* key= NULL;
    enum e_Glua_Type type;

    while( glua_tableKey( &key, &type )
        {
        if (type == GLUA_TYPE_STRING)
            {
            str= glua_getTable_str( key );  // (can also use 'NULL' here)
            }
        ...            
        }

Note: The use of NULL above gives slightly better performance since the values are actually available already at 'glua_tableKey()' call. Both work and it is up to you how you want to code. To dive into subtables of the iterated one, use ".subkey" notation (see 'sample.c'). Here you have to know the structure of the subtables - only the uppermost table can be iterated.

Note: Any integer parts in your key string (s.a. "my.123.obj") are automatically converted to numbers. Lua actually differs between 'tbl[123]' and 'tbl["123"]'. With GluaX, accessing the latter is not possible (wave your hand if you care! ;).

Note: When you use 'glua_tableKey()', you need to loop through all the keys until the function returns FALSE. Otherwise, temporary values are left on the stack that might cause interference later on.

To get the total number of table items ('glua_tableKey()' loops), you can use:

    glua_tableN()
This is useful e.g. if you need to allocate some C data structure before calling 'glua_tableKey()'.

The remaining get macros are:

    glua_argn()      // number of function arguments (0..N)
    glua_type(argn)  // type of a certain parameter (GLUA_TYPE_xxx, see 'gluax.h')
    glua_isInteger(argn)
    glua_isNumber(argn)
    glua_isString(argn)
    glua_isUserdata(argn)
    glua_isTable(argn)
    glua_isNil(argn)

These are especially usable in functions with variable parameter lists and/or parameter types. There is no 'glua_isBoolean' since any non-nil data is regarded as 'true' in Lua. You may use 'glua_isNil' instead.

Note: 'glua_getDone()' was discontinued 3-Jul-2003, use 'glua_argn()' instead.

Pushing return values to Lua

As already stated, you can return multiple values from a single Lua function call. This is done by pushing new values onto the Lua stack, with the following macros:

    glua_pushInteger(int v)
    glua_pushNumber(double v)
    glua_pushString(const char* str)
    glua_pushLString(const char* str, size_t len)
    glua_pushUserdata(int tag, size_t size, const void* p)
    glua_pushBoolean(bool_int b)
    glua_pushNil()
    glua_pushTable()

'pushUserdata()' can be used in three ways, depending on your needs:

Note: In the first two options, only one memory block is allocated (jointly for both Lua & your code) and thus they should be the preferred methods.

'glua_pushNil()' is sort of commentary, since pushing no values will default to 'nil'. However, it can be used to fill in 'empty slots' when several return values are used.

The last macro, 'pushTable()' is not very usable in itself (it just pushes an empty table to the stack) but when followed by 'glua_setTable...' macros, you can create as complicated data structures as you like and pass them back to Lua.

    glua_setTable_int(key,int)
    glua_setTable_num(key,double)
    glua_setTable_str(key,str)
    glua_setTable_lstr(key,str,len)
    glua_setTable_ud(key,void*,tag)
    glua_setTable_bool(key,void*,bool)

As with 'getTable' macros, also here keys may contain "dot notation" to automatically create subtables (e.g. setTable_int("background.color.green",200) ). Arrays can be created by having numeric strings (s.a. "1.3.7"). In C++ also integers, integer pairs and int+string combinations can be used directly as the key.

Other interface functions

These are the remaining functions that can be used within GLUA_FUNC blocks.

    void glua_error( const char* msg )
    void glua_errorN( const char* msg, ... )

Issues a Lua error from within the C code and never returns. The 'msg' string may contain printf-style formatting ("%s", "%d" etc.).

    void  glua_setAttachment( void* ud, void* attachment_ptr )
    void* glua_getAttachment( void* ud, bool remove )

Used for passing info from the userdata constructor to the users and/or destructors. Experimental.

There may also be other macros and/or functions that have not been discussed here. Most of these are either new or experimental and will be added here once their usage has become stable.


Callbacks

Sometimes, the C/C++ code needs to call back Lua functions. This happens i.e. with User Interface events and other such case.

To facilitate this need, use the following GluaX structure within your C/C++ callback function:

    GLUA_CALLBACK( this, "eventKeyDown" )
        {
        glua_pushString( str );
        glua_pushNumber( num );
        
        glua_call();    // Calls Lua code, any results to stack (LUA_MULTRET)

        ok= glua_getBoolean(1);
        }
    GLUA_CALLBACK_END

Note that this code goes within a regular function and not a GLUA_FUNC block. After all, it is the C/C++ code that's calling us back.


Static linkage

If you want to link your module statically with the main application (and the Lua engine) do as follows:

You can also link in several premade modules (using their GLUA_MODULE blocks as entry points). If you need to do this, have a deep look at 'gluahost.c' and 'sys_module.c'.


Frequently Asked Questions


Credits



GluaX follows the original Glua 1.0 license.