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

3 篇文章 0 订阅
1 篇文章 0 订阅

因为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")


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值