lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Steve Litt once stated:
> On Wednesday 19 January 2011 20:56:18 HyperHacker wrote:
> 
> > however are a Lua script that loads a bunch of modules (some of which
> > are written in C); it's not infeasible that a game engine could be
> > done that way.
> 
> I'm glad you responded. In my research I've found no examples of how to start 
> in Lua and load C modules, nor any documentation of same. Do you know of a 
> trivial "hello world" application of calling C from Lua for Lua 5.1?

  Here's one for Unix (tested under Linux) I wrote.  Creates a table, fills
it with a few values, the current working directory, the current PID and the
load average (an array); the load average has a metatable controlling how
it's printed.

[spc]lucy:/tmp>gcc -g -shared -fPIC -o silly.so silly.c
[spc]lucy:/tmp>lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> require "silly"
> x = silly.info()
> print(x.cwd,x.pid,x.loadave)
/tmp    22647   (0.06 0.04 0.01)
> os.exit()
[spc]lucy:/tmp>

  -spc (Code follows ... )

/****************************************************************************
*
* A silly example of extending lua via the shared object method.
* Here's how this is done under Linux:
*
*	gcc -g -fPIC -shared -o silly.so silly.c
*
* You will then have a shared object you can load into the lua interpreter.
*
*****************************************************************************/

#define _BSD_SOURCE

#include <stddef.h>
#include <string.h>
#include <stdlib.h>

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

#include <unistd.h>

/******************************************************************/

static int silly_loadave__toprint(lua_State *L)
{
  char       buffer[BUFSIZ];
  lua_Number load[3];
  int        i;
  
  if (lua_type(L,1) != LUA_TTABLE)
    return luaL_error(L,"Expecting table, but got %s",luaL_typename(L,1));
  
  for (i = 0 ; i < 3 ; i++)
  {
    lua_pushinteger(L,i + 1);
    lua_gettable(L,1);
    load[i] = luaL_checknumber(L,-1);
  }
  
  sprintf(buffer,"(%.2f %.2f %.2f)",load[0],load[1],load[2]);
  lua_pushstring(L,buffer);
  return 1;
}

/*******************************************************************/

static int silly_loadave__newindex(lua_State *L)
{
  return luaL_error(L,"Attempting to upate a read-only table");
}

/******************************************************************/

static int info(lua_State *L)
{
  lua_newtable(L);
  
  lua_pushliteral(L,"pid");
  lua_pushnumber(L,getpid());
  lua_settable(L,-3);
  
  char buffer[FILENAME_MAX];
  
  getcwd(buffer,FILENAME_MAX);
  lua_pushliteral(L,"cwd");
  lua_pushlstring(L,buffer,strlen(buffer));
  lua_settable(L,-3);

  double load[3];
  
  if (getloadavg(load,3) != -1)
  {
    /*----------------------------------------------
    ; equiv of
    ;	loadave = {}
    ;	loadave[1] = x;
    ;	loadave[2] = y;
    ;	loadave[3] = z;
    ;----------------------------------------------*/
    
    lua_pushliteral(L,"loadave");
    lua_createtable(L,3,0);
    
    lua_pushnumber(L,1);
    lua_pushnumber(L,load[0]);
    lua_settable(L,-3);
    
    lua_pushnumber(L,2);
    lua_pushnumber(L,load[1]);
    lua_settable(L,-3);
    
    lua_pushnumber(L,3);
    lua_pushnumber(L,load[2]);
    lua_settable(L,-3);
    
    /*---------------------------------------------
    ; mt = {}
    ; mt.__tostring = silly_loadave__toprint
    ; mt.__newindex = silly_loadave__newindex
    ; setmetable(loadave,mt);
    ;---------------------------------------------*/
    
    lua_createtable(L,0,2);
    lua_pushliteral(L,"__tostring");
    lua_pushcfunction(L,silly_loadave__toprint);
    lua_settable(L,-3);
    
    lua_pushliteral(L,"__newindex");
    lua_pushcfunction(L,silly_loadave__newindex);
    lua_settable(L,-3);
    
    lua_setmetatable(L,-2);
    
    lua_settable(L,-3);
  }

  return 1;
}

/************************************************************************/  

static const struct luaL_reg reg_silly[] = 
{
  { "info" , info },
  { NULL   , NULL } 
};

int luaopen_silly(lua_State *L)
{
  luaL_register(L,"silly", reg_silly);  
  return 1;
}

/************************************************************************/