在lua中使用C语言编写的库
因为lua比较小巧所以他本身并没有包含强大的库,但我们可以为lua扩展库,今天主要说明以下怎么在lua中使用C语言编写的库(windows下生成dll,linux下生成so),在库函数中必须包含一个luaopen_yourlibname的函数,库名可以自己定,
·
因为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")
更多推荐
已为社区贡献2条内容
所有评论(0)