lua-users home
lua-l archive

Re: Example to minimize redundancy of two libraries. Lua - C library & plain C library?

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


It was thus said that the Great Patrick Mc(avery once stated:
> Hi Everyone
> 
> After many long delays I think I am ready to start writing a scientific 
> instrument control library. I would like the library to be callable from 
> Lua but also just from C without Lua. I am assuming that the best way to 
> go about this is to write a plain C core and then a wrapper around it 
> with the Lua - C API and then to write another C wrapper around the core 
> for a plain C library.
 I've dome something like this at work. For instance, we have a custom
data file we use for a few of our components, so I wrote a C API to
manipulate these files, with the API looking something like:
foodblib.h:
	typedef struct foodb { /* ... */ } foodb__t;
	typedef struct foorec { /* ... */ } foorec__t;
	int foodblib_open	(foodb__t *,const char *name,int mode);
	int foodblib_index_i	(foodb__t *,foorec__t *,size_t idx);
	int foodblib_index_s	(foodb__t *,foorec__t *,const char *idx);
	int foodblib_add_i	(foodb__t *,foorec__t *,size_t idx);
	int foodblib_add_s	(foodb__t *,foorec__t *,const char *idx);
	int foodblib_del_i	(foodb__t *,foorec__t *,size_t idx);
	int foodblib_del_s	(foodb__t *,foorec__t *,const char *idx);
	int foodblib_close	(foodb__t *);
And foodblib.c would be the implementation of the C API. The Lua interface
would be in foodblua.h/foodblua.c and is basically as thin a wrapper as I
can get, with a similar naming convention:
foodblua.h
	int foodblua_open	(lua_State *);
	int foodblua___index	(lua_State *);
	int foodblua___newindex (lua_State *);
	int foodblua___gc	(lua_State *);
foodblua.c
	/* sample implementation */
	int foodblua___indexi(lua_State *L)
	{
	 foodb__t *db = luaL_checkudate(L,1,FOODB);
	 foorec__t rec;
	 int rc;
 
	 if (lua_type(L,2) == LUA_TNUM)
	 rc = foodblib_index_i(db,&rec,lua_tointeger(L,2));
	 else if (lua_type(L,2) == LUA_TSTRING)
 	 rc = foodblib_index_s(db,&rec,lua_tostring(L,2));
	
	 if (rc == ERROR) /* handle error */
	 lua_createtable(L,0,0);
	 /* push fields from rec into Lua table */
	 return 1;
	}
 If I'm coding in C, I use the C API (the foodblib* calls); whereas if I'm
in Lua, I indirectly use the Lua API (ultimately, the foodblua* calls). It
seems straightforward to me, and the API mapping between C and Lua is close
enough to figure out what's going on. 
 -spc

AltStyle によって変換されたページ (->オリジナル) /