LUA 源码阅读笔记(一)
2011-11-08 11:37
253 查看
好久没有在网上留言了。。。
背景介绍
因为工作的需要,后台svr要能够动态修改更新,使用C当然没有问题,问题就在于修改源码后,需要重启服务。所以就想到在C里能够嵌入一种脚本,最好是和C无缝结合的。因此就想到使用到LUA,LUA的大名圈内人士应该早有耳闻,只不过一直没有机会接触。机缘巧合,有幸一见。
俗话说得好,耳闻不如一见。LUA使用起来还是很简单的,语法和普通的脚本语言相差不大,很容易上手。在实际项目的使用过程中,对LUA性能的体验也是感受尤深。这也是决定一探LUA源码的动力所在。因此,本笔记也只是针对LUA源码的相关记录,不会涉及到LUA使用上的一些问题。同时,也欢迎各位LUA爱好者批评指正笔记中的错误之处。废话不说了,切入正题。
(1)mathlib strlib
mathlib 和 strlib是lua的一个基本库,每个函数的实现都是在在基本库的基础上重新封装,举个例子
调用基本库fabs()函数,将返回的结果压栈返回。那肯定有一个疑问,就是参数怎么传递进去的?是呀,参数怎么传递进去的,我现在也不知道,但是不要紧,先有个印象就行。
还要明白一点,外界不会直接调用math_abs(),为什么?static呀,如果不明白的,先修炼一下C的基本功吧,下面继续来猜测外面怎么调用这些函数。
上面这个结构体定义了内部函数名(或者是函数指针)与外部函数名之间的映射关系,比如要调用math_abs(),那实际使用的就是abs()来调用,目前,这还是猜测,是不是这样还有待验证。
那luaL_Reg 是啥,看如下声明:
就是一个名字,和一个函数指针,
lua如何将这个映射注册进去呢,看下面的函数,这个是mathlib的外部唯一接口
大概的意思就是将mathlib这个luaL_Reg对象在L中注册登记,L是什么,L就是lua_State*!!!!!等于没说,但是目前的认知也就是这些,这是最准确的表述,不是吗?从名字上看,应该是一个状态机。想知道到底是什么,接着看代码。注册登记完了,将一些常量压栈。应该是设置一些环境变量,等等。
strlib和mathlib的结构差不多,
也是重新封装一大堆函数,然后通过一个唯一接口来注册所有的函数。实际使用的时候,也就是调用这个唯一的接口。调用完该接口,应该就可以在那个叫做lua_State*的L中使用这些基本库函数了。
到目前为止,很多还是不确定的,比如lua_State是什么,为什么基本库的注册登记,都要向针对这个L进行。L中到底维护的是什么信息,翻开lua_State的定义,一大堆数据,很多都不知道是什么。好吧,先不看这个,先继续看别的,但是要知道这个就是一个结构体就行,这个结构体里面肯定维护很多核心的东西。
背景介绍
因为工作的需要,后台svr要能够动态修改更新,使用C当然没有问题,问题就在于修改源码后,需要重启服务。所以就想到在C里能够嵌入一种脚本,最好是和C无缝结合的。因此就想到使用到LUA,LUA的大名圈内人士应该早有耳闻,只不过一直没有机会接触。机缘巧合,有幸一见。
俗话说得好,耳闻不如一见。LUA使用起来还是很简单的,语法和普通的脚本语言相差不大,很容易上手。在实际项目的使用过程中,对LUA性能的体验也是感受尤深。这也是决定一探LUA源码的动力所在。因此,本笔记也只是针对LUA源码的相关记录,不会涉及到LUA使用上的一些问题。同时,也欢迎各位LUA爱好者批评指正笔记中的错误之处。废话不说了,切入正题。
(1)mathlib strlib
mathlib 和 strlib是lua的一个基本库,每个函数的实现都是在在基本库的基础上重新封装,举个例子
static int math_abs (lua_State *L) { lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); return 1; }
调用基本库fabs()函数,将返回的结果压栈返回。那肯定有一个疑问,就是参数怎么传递进去的?是呀,参数怎么传递进去的,我现在也不知道,但是不要紧,先有个印象就行。
还要明白一点,外界不会直接调用math_abs(),为什么?static呀,如果不明白的,先修炼一下C的基本功吧,下面继续来猜测外面怎么调用这些函数。
static const luaL_Reg mathlib[] = { {"abs", math_abs}, {"acos", math_acos}, {"asin", math_asin}, {"atan2", math_atan2}, {"atan", math_atan}, {"ceil", math_ceil}, {"cosh", math_cosh}, {"cos", math_cos}, {"deg", math_deg}, {"exp", math_exp}, {"floor", math_floor}, {"fmod", math_fmod}, {"frexp", math_frexp}, {"ldexp", math_ldexp}, {"log10", math_log10}, {"log", math_log}, {"max", math_max}, {"min", math_min}, {"modf", math_modf}, {"pow", math_pow}, {"rad", math_rad}, {"random", math_random}, {"randomseed", math_randomseed}, {"sinh", math_sinh}, {"sin", math_sin}, {"sqrt", math_sqrt}, {"tanh", math_tanh}, {"tan", math_tan}, {NULL, NULL} };
上面这个结构体定义了内部函数名(或者是函数指针)与外部函数名之间的映射关系,比如要调用math_abs(),那实际使用的就是abs()来调用,目前,这还是猜测,是不是这样还有待验证。
那luaL_Reg 是啥,看如下声明:
typedef struct luaL_Reg { const char *name; lua_CFunction func; } luaL_Reg;
就是一个名字,和一个函数指针,
typedef int (*lua_CFunction) (lua_State *L);
lua如何将这个映射注册进去呢,看下面的函数,这个是mathlib的外部唯一接口
LUALIB_API int luaopen_math (lua_State *L) { luaL_register(L, LUA_MATHLIBNAME, mathlib); lua_pushnumber(L, PI); lua_setfield(L, -2, "pi"); lua_pushnumber(L, HUGE_VAL); lua_setfield(L, -2, "huge"); #if defined(LUA_COMPAT_MOD) lua_getfield(L, -1, "fmod"); lua_setfield(L, -2, "mod"); #endif return 1; }
大概的意思就是将mathlib这个luaL_Reg对象在L中注册登记,L是什么,L就是lua_State*!!!!!等于没说,但是目前的认知也就是这些,这是最准确的表述,不是吗?从名字上看,应该是一个状态机。想知道到底是什么,接着看代码。注册登记完了,将一些常量压栈。应该是设置一些环境变量,等等。
strlib和mathlib的结构差不多,
也是重新封装一大堆函数,然后通过一个唯一接口来注册所有的函数。实际使用的时候,也就是调用这个唯一的接口。调用完该接口,应该就可以在那个叫做lua_State*的L中使用这些基本库函数了。
到目前为止,很多还是不确定的,比如lua_State是什么,为什么基本库的注册登记,都要向针对这个L进行。L中到底维护的是什么信息,翻开lua_State的定义,一大堆数据,很多都不知道是什么。好吧,先不看这个,先继续看别的,但是要知道这个就是一个结构体就行,这个结构体里面肯定维护很多核心的东西。
相关文章推荐
- skynet 源码阅读笔记 bootstrap.lua
- spark源码阅读笔记RDD(四)RDD中WithScope是什么?
- OBS源码阅读笔记--如何修改录播文件路径到exe所在目录
- Redux 学习笔记 - 源码阅读
- Spark源码阅读笔记:Spark的数据系统之cache篇
- SDL源码阅读笔记(1) 基本模块
- Yii源码阅读笔记 - 应用模块化
- Laravel 5.1 源码阅读笔记
- OBS源码阅读笔记---32位编译
- HashMap源码阅读笔记
- Handsfree_hw节点 源码阅读笔记
- AFNetworking 3.0 源码阅读笔记(六)
- linux-Tcp IP协议栈源码阅读笔记
- 阅读源码遇到的一些Python 函数(--小白笔记)
- Glide源码阅读笔记(二)全局配置,https自签名处理,自定义图片下载
- GPGPU-Sim 源码阅读笔记 之 cache option默认策略
- IPMsg源码阅读笔记(1)
- winvnc源码阅读笔记(三)---------vncClient::SendUpdate线程
- Redis源码阅读笔记—sds
- SDL源码阅读笔记(3)渲染模块