您的位置:首页 > 编程语言 > Lua

在lua中使用C语言编写的库

2011-07-05 14:27 218 查看
因为lua比较小巧所以他本身并没有包含强大的库,但我们可以为lua扩展库,今天主要说明以下怎么在lua中使用C语言编写的库(windows下生成dll,linux下生成so),在库函数中必须包含一个luaopen_yourlibname的函数,库名可以自己定,该函数也是lua_CFunction的类型,主要作用是将你所编写的库中的函数使用lua_register函数将其注册供lua中使用。通过下面的代码可以看到lua的扩展性非常强大。在lua中只需要require "yourlibname"即可或者用loadlib函数. 下面这个例子是为lua提供一个遍历目录的库,

C库代码如下:
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <malloc.h>

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

#ifndef MAX_PATH
#define MAX_PATH		260
#endif

enum
{
PQFT_UNKNOWN = 0,
PQFT_FILE = 1,
PQFT_DIR = 2
};

typedef struct
{
DIR	*	dir;
char 	curr_path[MAX_PATH];
}PQDIR;

static int search_dir_first(lua_State *L)
{
PQDIR * pd = NULL;
const char *dir_path = luaL_checkstring(L, 1);

if ( dir_path ) {
pd = (PQDIR *)malloc(sizeof(PQDIR));
if ( pd ) {
pd->dir = opendir(dir_path);
if ( pd->dir ) {
memset(pd->curr_path, 0, MAX_PATH);
memcpy(pd->curr_path, dir_path, strlen(dir_path));
lua_pushboolean(L, 1);
lua_pushlightuserdata(L, pd);
return 2;
}
}
}

lua_pushboolean(L, 0);
lua_pushnil(L);
return 2;
}

static int search_dir_next(lua_State *L)
{
char filepath[MAX_PATH];
struct dirent *ent = NULL;
struct stat	file_stat;
PQDIR *pd = (PQDIR *)lua_touserdata(L, 1);

if ( pd ) {
if ( (ent = readdir(pd->dir)) ) {
lua_pushboolean(L, 1);
lua_pushstring(L, ent->d_name);
sprintf(filepath, "%s/%s", pd->curr_path, ent->d_name);
lstat(filepath, &file_stat);
if ( S_ISDIR(file_stat.st_mode) && !S_ISLNK(file_stat.st_mode) ) {
lua_pushnumber(L, PQFT_DIR);
} else if ( S_ISREG(file_stat.st_mode) && !S_ISLNK(file_stat.st_mode) ) {
lua_pushnumber(L, PQFT_FILE);
} else {
lua_pushnumber(L, PQFT_UNKNOWN);
}
return 3;
}
}

lua_pushboolean(L, 0);
lua_pushnil(L);
lua_pushnil(L);
return 3;
}

static int search_dir_finish(lua_State *L)
{
PQDIR *pd = (PQDIR *)lua_touserdata(L, 1);
if ( pd ) {
closedir(pd->dir);
free(pd);
pd = NULL;
}
return 0;
}

int luaopen_pqdir(lua_State *L)
{
lua_pushnumber(L, PQFT_UNKNOWN);
lua_setglobal(L, "PQFT_UNKNOWN");
lua_pushnumber(L, PQFT_FILE);
lua_setglobal(L, "PQFT_FILE");
lua_pushnumber(L, PQFT_DIR);
lua_setglobal(L, "PQFT_DIR");

lua_register(L, "search_dir_first", search_dir_first);
lua_register(L, "search_dir_next", search_dir_next);
lua_register(L, "search_dir_finish", search_dir_finish);

return 0;
}
使用gcc -shared pqdir.c -o pqdir.so -llua -ldl -lm命令将其生存so文件

lua代码如下:
require "pqdir"

function traverse_dir(dirpath)
print("search: " .. dirpath)
local bok, dir = search_dir_first(dirpath)
if bok then
while true do
local b, filename, filetype = search_dir_next(dir)
if b then
local fullpath = dirpath .. "/" .. filename
if filetype == PQFT_DIR then
if filename == "." then
elseif filename == ".." then
else traverse_dir(fullpath)
end
else
print(fullpath)
end
else
break
end
end
search_dir_finish(dir)
end
end

traverse_dir("/usr")
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: