近来研究Lua这个东西,官网为http://www.lua.org/
主要的目的是通过lua来对短信发送过来的业务报文转换为业务系统支持的格式,设计的思想是Lua进行业务报文的转换,报文的通讯采用c实现,因为要通过C实现SGIP协议报文的封装和到后台业务的转换。
C调用Lua函数- 首先要进行Lua的初始化,这个主要是lua_open和luaL_openlibs函数
- 然后是解析并编译lua的代码,这个主要是luaL_dofile函数
- 解析好之后使用lua_getglobal指明要调用的lua函数
- 如果有lua函数的参数,通过使用lua_pushstring函数传递参数
- 最后调用lua_pcall进行lua函数的调用
- 调用完成之后采用lua_tonumber类函数可以获取到函数的返回结果
- 在Lua中调用C的函数,该函数必须进行注册,这个通过lua_register这个函数来完成
- 在Lua中调用注册的函数,会调用上面注册的函数(类似于回调),所有的处理在这个函数里面
- 这个函数里面可以使用lua_tostring类函数来获取函数的参数
- 如果有返回值,通过lua_pushnumber这个函数来返回。
下面的这个代码是用来将联通的短信进行报文的转换,同时对Lua注册了一个SendSms函数用来可以在Lua中发送短信。
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#define cutil_log_error printf
#define cutil_log_debug printf
/**
* LuaSendSms
* 当Lua里面调用SendSms函数时候会触发该函数
*/
static int LuaSendSms(lua_State *L)
{
char *pszPhone = "";
char *pszMessage = "";
// 读取并判读参数
if(lua_gettop(L) != 2)
{
lua_pushstring(L, "Incorrect argument number!");
lua_error(L);
}
if(!lua_isnumber(L, 1) || !lua_isstring(L, 2))
{
lua_pushstring(L, "Incorrect argument!");
lua_error(L);
}
pszPhone = lua_tostring(L, 1);
pszMessage = lua_tostring(L, 2);
// 发送消息 TODO
cutil_log_debug("Send Message %s to %s.\n", pszMessage, pszPhone);
// 返回结果
lua_pushnumber(L, 0);
// 只有一个返回结果
return 1;
}
/**
* LuaProcessSms
* 调用Lua里面的LuaMain函数进行消息的处理
*/
static int LuaProcessSms(lua_State *L, char *pszPhone, char *pszMessage)
{
int nRet;
char *pszRetInfo;
cutil_log_debug("process phone %s message %s\n", pszPhone, pszMessage);
// 调用函数和参数
lua_getglobal(L, "LuaMain");
lua_pushstring(L, pszPhone);
lua_pushstring(L, pszMessage);
if(nRet = lua_pcall(L, 2, 2, 0))
{
cutil_log_error("lua_pcall error ret %d error '%s'. phone %s message %s\n",
nRet, lua_tostring(L, -1), pszPhone, pszMessage);
lua_settop(L, 0);
return -1;
}
// 判读返回参数合法性
if(lua_gettop(L) != 2)
{
cutil_log_error("Incorrect return number. %d phone %s message %s\n",
lua_gettop(L), pszPhone, pszMessage);
lua_settop(L, 0);
return -1;
}
if(!lua_isnumber(L, 1) || !lua_isstring(L, 2))
{
cutil_log_error("Incorrect return. arg1 %s arg2 %s phone %s message %s\n",
lua_tostring(L, 1), lua_tostring(L, 2),
pszPhone, pszMessage);
lua_settop(L, 0);
return -1;
}
// 获取并处理返回信息 TODO
nRet = lua_tonumber(L, 1);
pszRetInfo = strdup(lua_tostring(L, 2));
lua_settop(L, 0);
cutil_log_debug("Ret %d Info %s\n", nRet, pszRetInfo);
if(nRet != 0)
{
cutil_log_error("process info error phone %s message %s ret %d info %s\n",
pszPhone, pszMessage, nRet, pszRetInfo);
free(pszRetInfo);
return -1;
}
free(pszRetInfo);
return 0;
}
/**
* LuaInit
* 初始化Lua库,并注册一个SendSms函数
*/
static lua_State *LuaInit()
{
lua_State *L = lua_open();
if(L == NULL)
{
cutil_log_error("Init the lua library error\n");
return NULL;
}
luaL_openlibs(L);
/* register our function */
lua_register(L, "SendSms", LuaSendSms);
return L;
}
int main()
{
int i;
lua_State *L;
L = LuaInit();
if (luaL_dofile(L, "sms.lua"))
error(L, "cannot run configuration file: %s",
lua_tostring(L, -1));
for(i = 0; i < 1; i ++)
LuaProcessSms(L, "13988227711", "测试消息");
lua_close(L);
}
下面是参考的Lua程序
-- 函数名称必须为LuaMain
-- 函数里面可以调用SendSms进行消息发送,第一个参数是手机号码,第二个参数是内容
-- 函数的参数有两个phone是手机号码 message是接收到的短信内容
-- 返回参数有两个 第一个是返回值0表示成功,其他失败,第二个是要求发送的内容
function LuaMain(phone, message)
print("phone ", phone, "message", message)
SendSms('13988221133', '你好')
return 0,'KZCZ函数的参数有两个phone是手机号码 message是接收到的短信内容'
end
-- 这个里面可以有全局的代码,不过建议不要编写
-- 全局的代码会在LuaMain函数之前运行