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

lua中集成第三方拓展c库

2016-01-22 17:56 411 查看

将第三方c库添加到工程中(lua调用c/c++)

以luasocket.c为例,第三方socket库

static const luaL_Reg mod[] = {
{"auxiliar", auxiliar_open},
{"except", except_open},
{"timeout", timeout_open},
{"buffer", buffer_open},
{"inet", inet_open},
{"tcp", tcp_open},
{"udp", udp_open},
{"select", select_open},
{NULL, NULL}
};


这里是关于所有的这个库中需要使用的函数的数组。将luaL_Reg这个结构体展开便可得知这个数组中每个元素的含义了。(在lauxlib.h中定义的)

typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg;


再将lua_CFunction展开看下(在lua.h中定义)

typedef int (*lua_CFunction) (lua_State *L);


这个就定义了所有的用这种方式的函数的定义规则。

在lua中传入的参数是如何传给c代码?都是通过类似的函数LuaL_checkXXXX来从栈中取得。将返回值Push到栈中,函数返回值是返回值的个数。

而大量的luaL_XXX这种命名规则,是代表此函数不是LUA的核心代码。

再来看这个luasocket.c文件中的另一段代码

static int base_open(lua_State *L) {
if (socket_open()) {
/* export functions (and leave namespace table on top of stack) */
lua_newtable(L);
luaL_setfuncs(L, func, 0);
#ifdef LUASOCKET_DEBUG
lua_pushstring(L, "_DEBUG");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#endif
/* make version string available to scripts */
lua_pushstring(L, "_VERSION");
lua_pushstring(L, LUASOCKET_VERSION);
lua_rawset(L, -3);
return 1;
} else {
lua_pushstring(L, "unable to initialize library");
lua_error(L);
return 0;
}
}

/*-------------------------------------------------------------------------*\
* Initializes all library modules.
\*-------------------------------------------------------------------------*/
LUASOCKET_API int luaopen_socket_core(lua_State *L) {
int i;
base_open(L);
for (i = 0; mod[i].name; i++) mod[i].func(L);
return 1;
}


这个是将该函数作为一个模块放在一个table中。里面有函数地址等等。LUASOCKET_API就是extern 供其他文件直接引用.

linit.c这个文件非常重要

/*
** these libs are loaded by lua.c and are readily available to any Lua
** program
*/
static const luaL_Reg loadedlibs[] = {
{"_G", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_COLIBNAME, luaopen_coroutine},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_UTF8LIBNAME, luaopen_utf8},
{LUA_DBLIBNAME, luaopen_debug},
#if defined(LUA_COMPAT_BITLIB)
{LUA_BITLIBNAME, luaopen_bit32},
#endif
{LUA_SOCKETLIBNAME, luaopen_socket_core},
{LUA_MIMELIBNAME, luaopen_mime_core},
{NULL, NULL}
};


loadLibs LuaL_Reg是之前看到的结构体。以luasocket库为例:(在lualib.h中定义)

#define LUA_SOCKETLIBNAME "socket"
LUAMOD_API int (luaopen_socket_core) (lua_State *L);

#define LUA_MIMELIBNAME "mime"
LUAMOD_API int (luaopen_mime_core) (lua_State *L);


而这里的名字就是我们要在lua中使用的模块名。 下面是用来外链函数的。以下是luaL_openlibs

LUALIB_API void luaL_openlibs (lua_State *L) {
const luaL_Reg *lib;
/* "require" functions from 'loadedlibs' and set results to global table */
for (lib = loadedlibs; lib->func; lib++) {
luaL_requiref(L, lib->name, lib->func, 1);
lua_pop(L, 1);  /* remove lib */
}
}


将类库都加载到虚拟机中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: