原文链接:http://www.voidcn.com/article/p-ahfakqsx-bac.html
本文对原文有修改。
概述
C调用Lua函数
- 首先要进行Lua的初始化,这个主要是lua_open和luaL_openlibs函数
- 然后是解析并编译lua的代码,这个主要是luaL_dofile函数
- 解析好之后使用lua_getglobal指明要调用的lua函数
- 如果有lua函数的参数,通过使用lua_pushstring函数传递参数
- 最后调用lua_pcall进行lua函数的调用
- 调用完成之后采用lua_tonumber类函数可以获取到函数的返回结果
Lua调用C函数
- 在Lua中调用C的函数,该函数必须进行注册,这个通过lua_register这个函数来完成
- 在Lua中调用注册的函数,会调用上面注册的函数(类似于回调),所有的处理在这个函数里面
- 这个函数里面可以使用lua_tostring类函数来获取函数的参数
- 如果有返回值,通过lua_pushnumber这个函数来返回。
参考的代码
#include <lua.h> #include <lauxlib.h> #include <lualib.h>
#include <stdio.h> #include <string.h> #include <malloc.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,0)) { cutil_log_error("lua_pcall error ret %d error '%s'. phone %s message %s\n",nRet,lua_tostring(L,-1),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),0); return -1; } if(!lua_isnumber(L,2)) { cutil_log_error("Incorrect return. arg1 %s arg2 %s phone %s message %s\n",1),2),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",pszRetInfo); if(nRet != 0) { cutil_log_error("process info error phone %s message %s ret %d info %s\n",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",-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函数之前运行但我发现中文出现乱码。