Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedding Lua 5.2 and defining libraries

Tags:

c

embed

lua

Lua comes with a free on-line reference manual for version 5.2 (which I am using) and Programming in Lua for version 5.0 is also available.

There have been, however, a couple of changes between these versions that I cannot seem to be able to surpass. The changes are noted in the successive versions of the reference manual for 5.2 and 5.1. Notice the successive deprecation of luaL_openlib() in favour of luaL_register(), then luaL_register() in favor of luaL_setfuncs().

The searches on the web give mixed results, with most of them pointing to luaL_register().

What I try to achieve may be summarized by the mini-program below that may be compiled and linked with say, gcc ./main.c -llua -ldl -lm -o lua_test

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

#include <stdio.h>
#include <string.h>


static int test_fun_1( lua_State * L )
{
    printf( "t1 function fired\n" );
    return 0;
}

int main ( void )
{
    char buff[256];
    lua_State * L;
    int error;

    printf( "Test starts.\n\n" );

    L = luaL_newstate();
    luaL_openlibs( L ); 

    lua_register( L, "t1", test_fun_1 );

    while ( fgets( buff, sizeof(buff), stdin ) != NULL)
    {
      if ( strcmp( buff, "q\n" ) == 0 )
      {
          break;
      }
      error = luaL_loadbuffer( L, buff, strlen(buff), "line" ) ||
              lua_pcall( L, 0, 0, 0 );
      if (error)
      {
        printf( "Test error: %s\n", lua_tostring( L, -1 ) );
        lua_pop( L, 1 );
      }
    }
    lua_close( L );

    printf( "\n\nTest ended.\n" );
    return 0;
 }

This works as expected and typing t1() produces the expected result.

I would now like to create a library/package visible to Lua. The Programming in Lua advices us to use an array and a load function:

static int test_fun_2( lua_State * L )
{
    printf( "t2 function fired\n" );
    return 0;
}

static const struct luaL_Reg tlib_funcs [] =
{
  { "t2", test_fun_2 },
  { NULL, NULL }  /* sentinel */
};

int luaopen_tlib ( lua_State * L )
{
  luaL_openlib(L, "tlib", tlib_funcs, 0);

  return 1;
}

then use luaopen_tlib() after luaL_openlibs(). Doing so allows us to use tlib:t2() if we define LUA_COMPAT_MODULE (work in compatible mode).

What is the proper way of doing this in Lua 5.2?

like image 811
Nicu Tofan Avatar asked Nov 18 '12 18:11

Nicu Tofan


1 Answers

The luaopen_tlib function should be written that way:

int luaopen_tlib ( lua_State * L )
{
  luaL_newlib(L, tlib_funcs);
  return 1;
}

And in the main function, you should load the module like this:

int main ( void )
{
    // ...
    luaL_requiref(L, "tlib", luaopen_tlib, 1);
    // ...
}

Or alternatively, you can add an entry {"tlib", luaopen_tlib} to the loadedlibs table in linit.c.

like image 77
prapin Avatar answered Oct 19 '22 22:10

prapin