lua中集成第三方拓展c库

将第三方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 */
  }
}

将类库都加载到虚拟机中。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值