无聊写的谷歌拼音颜文字扩展
谷歌输入法的颜文字扩展已经有好多了,反正也不差我再写一个吧 o(* ̄▽ ̄*)o ,表情比较多(300+)
源码和扩展文件都放在 Github 上了:https://github.com/tisyang/kaos
示例1:

示例2:


用 C 扩展写 Lua closure
这个是《programming in lua》中的有的一个例子,通过 closure(闭包)来实现一个 tuple(元组)。
元组是一种具有匿名字段的常量记录。可以用一个数字索引来检索某个字段,或者一次性检索所有字段。
这里的实现将元组表示为函数,元组的值存放在函数绑定的 upvalue 中。大概的 Lua 代码示意如下:
local tuple = {}
function tuple.new(...)
local t = {...}
return function(index)
if index then
if type(index) ~= "number" then error("invalid index type") end
if index < 0 then error("index is out of range") end
return t[index]
else
return unpack(t)
end
end
end
闭包工厂 tuple.new 中的 table t 就是用于存放元组内容的 upvalue,这个 tuple 的使用如下:
local x = tuple.new(10, "hi", {}, 4)
print(x(1))
print(x(2))
print(x())
当用一个数字参数来调用此函数时,它会返回指定的字段。当不用参数来调用此函数时,则返回所有的字段。输出为:
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
static int
t_tuple(lua_State *L)
{
int op = luaL_optint(L, 1, 0);
if (op == 0) { /* 无参数? */
int i;
/* 将所有合法 upvalue 压入栈中 */
for (i = 1; !lua_isnone(L, lua_upvalueindex(i)); i++)
lua_pushvalue(L, lua_upvalueindex(i));
return i - 1; /* 栈中值的数量 */
}
else { /* 获取 'op' 字段 */
luaL_argcheck(L, 0 < op, 1, "index out of range");
if (lua_isnone(L, lua_upvalueindex(op))) { /* 无此字段 */
lua_pushnil(L); /* 返回 nil 表明不存在 */
return 1;
}
lua_pushvalue(L, lua_upvalueindex(op));
return 1;
}
}
static int
t_new(lua_State *L)
{
lua_pushcclosure(L, t_tuple, lua_gettop(L));
return 1;
}
static const struct luaL_Reg tuplelib[] = {
{"new", t_new},
{NULL, NULL}
};
int luaopen_tuple(lua_State *L)
{
luaL_register(L, "tuple", tuplelib);
return 1;
}
编译成“tuple.dll”(windows 下)然后仍然用上面的 tuple 使用代码测试,不过要先“require 'tuple'”来加载这个扩展。DLL 中的需要导出 lutopen_tuple 这个函数符号。
t_new 是创建元组的工厂函数。将需要作为 upvalue 的参数实现压入栈中,然后调用 lua_pushcclosure 来创建一个基于 t_tuple 的 closure 。lua_gettop 返回栈的大小,在这里也就等于已经压入栈中作为 upvalue 的数量。lua_upvalueindex 是一个用来索引 upvalue 的宏,当索引一个不存在的 upvalue ,结果会是一个类型为 LUA_TNONE 的伪值(pseudo-value),当索引超出当前栈范围时候,也会得到这样的 LUA_TNONE 的伪值。不能以负数来调用 lua_upvalueindex ,所以做了范围检查,luaL_argcheck(L, 0 < op, 1, "index out of range") 第二个参数是个条件表达式,第三个是检查的参数数量,最后一个是检查失败传递的消息。
用于检测可选参数的函数是 luaL_optint ,它允许参数不存在,如果不存在,则返回一个指定的默认值,也就是最后一个参数。
给 lua 写 C 模块示例
主要内容出在《programming in lua》第二版 26章
本例是在 VS2008下,配合 lua on windows 包内的 lua 库使用。
1. 配置好 VS 的lua 环境,主要是引用的头文件目录,库目录,然后将 dll 加入 path 环境。
2. 新建一个 Win32 DLL 空项目(例如 "l_lib",这也是本例所提供的模块名),配置项目 链接器》输入》附加依赖库:lua5.1.lib
3. 添加一个 C 源文件:
#include <math.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
static int l_sin(lua_State *L)
{
double d = luaL_checknumber(L, 1);
lua_pushnumber(L, sin(d));
return 1;
}
static const struct luaL_Reg l_lib[] = {
{"l_sin", l_sin},
{NULL, NULL}
};
int luaopen_l_lib(lua_State *L)
{
luaL_register(L, "l_lib", l_lib);
return 1;
}
4. 给项目添加一个模块定义文件(.def),用于导出dll 符号:
require 'l_lib'
print(l_lib.l_sin(1))
所有注册到 Lua 中的函数都具有相同的原型,该原型就是定义在 lua.h 中的 lua_CFunction:typedef int (*lua_CFunction)(lua_State *L);从 C 语言的观点来看,这个 C 函数仅有一个参数,即 Lua 的状态。它返回一个整数,表示其压入栈中的返回值数量。因此,这个函数无须在压入结果前清空栈。在它返回后,Lua 会自动删除栈中结果之下的内容。
lua 之爱
《programming in lua》第二版的中文版这本书快看完了,中间夹杂着英文版的看,因为翻译并非完美,而且英文版的也很容易看懂。
这里是我的读书笔记:http://book.douban.com/people/tisyang/annotation/3076942/ 但并非每个要点都会有笔记。
lua 是一个值得学习的语言而且也不会需要过多时间,这本书是学 lua 一定要看的,云风 大神也这样推荐。
愈学愈爱
