本文讨论如何在lua中实现printf。学习的目的是为了进一步了解C函数和lua之间利用栈传值的过程。在lua中printf的功能等于string.format + io.wirte,前者用于格式化字符串,后者用于输出。文中的代码来自于lua官网。
用lua代码实现为:
printf= function(s, ...)
return io.write(s:format(...))
end
printf("%s\n", "Hello World!")
在C语言中实现为:
#include <Windows.h>
extern "C"{
#include <lua.h>
#include <lauxlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <lualib.h>
#include <math.h>
#include <limits.h>
}
static int l_printf (lua_State *L) {
lua_pushvalue(L, lua_upvalueindex(2)); //将format函数放置栈顶
lua_insert(L, 1); //将format函数插入至栈低,此时的栈内容为:string.format, arg1, arg2, ...
lua_call(L, lua_gettop(L) - 1, 1); //lua中的函数string.format和C语言中的printf是一样的,所以lua_gettop(L) - 1就是参数的个数。
//栈中只有:result
lua_pushvalue(L, lua_upvalueindex(1));//将write函数放置栈顶,栈中的内容为:result, io.write
lua_pushvalue(L, -2); //将io.write移到result之前,使result作为write的参数
lua_call(L, 1, 0); //调用write(result)
return 0;
}
int luaopen_printf (lua_State *L) {
lua_getglobal(L, "io");
lua_getglobal(L, "string");
lua_pushliteral(L, "write");//lua_upvalueindex(1)。等同于lua_pushstring,作用是将一个字符串放置于栈顶。
lua_gettable(L, -3); //-3是io在栈中的索引,在io table中查找key=write的项。如果找到,就将该项放入栈中,在放入之前删除之前压入的字符串"write"
lua_pushliteral(L, "format");//lua_upvalueindex(2)
lua_gettable(L, -3);
//将l_printf放置栈顶
lua_pushcclosure(L, l_printf, 2);//2表示为:在函数l_printf中,可以向上访问2个luaopen_printf栈中的值,即函数write和函数format。
//将栈顶元素(既l_printf)命名为printf,lua可以通过printf调用l_printf
lua_setglobal(L, "printf");
return 0;
}
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
luaopen_printf(L);
lua_pushstring(L, "lua is great!");
lua_setglobal(L, "lua"); //设置一个命名为lua的全局变量,其中的内容为字符串"lua is great!"
bool result = luaL_loadfile(L, "fordebug.lua");
if(!result) result = lua_pcall(L, 0, 0, 0);
lua_close(L);
system("pause");
return 0;
}
fordebug.lua中的代码:
printf("%s\n", lua) --> lua is great!
分享到:
相关推荐
《终极网络服务端编程》的lua server 实现了lua脚本处理服务端逻辑+数据库 lua服务端 c++版服务端客户端(netserver,netclient) lua服务端 就是 c++ netserver项目的lua脚本化版 运行效果 ![image]...
Lua中是没有类的概念的,但是程序猿说要面向对象,所以就有了。
lua类的实现
1、简单工厂模式lua实现 2、工厂方法模式lua实现 3、原型模式lua实现 4、建造者模式lua实现 5、单例模式lua实现 6、抽象工厂模式lua实现 结构型模式 1、装饰模式lua实现 2、代理模式lua实现 3、外观模式lua实现 4、...
lua实现 basse64 lua lua实现 basse64 lua lua实现 basse64 lua
lua实现webservice调用 通过gsoap 实现 C/C++ 调用web service
2048 源码 lua 逻辑实现
lua程序实现了对两个文件的比较;找出两个表中的非重叠项和键值不同的项
Lua语言实现特殊字符过滤,对于使用Lua开发移动端游戏的童鞋非常常用。代码亲测有效,附使用实例
Lua实现跟py的sleep一样的定时器功能,在倒计时结束时调用函数
cocos2d-lua 实现富文本
作者在研究了它的结构和 特点的基础上,对Lua运行环境中的堆栈结构进行了分析,由于引擎与Lua脚本 均能够操作堆栈中的数据,因此通过把堆栈作为两者信息传递的中间层,实现了 共用Lua全局变量、在引擎中引用脚本函数...
Lua飞机大战源码
Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。5.0.2版的Lua的内核小于120KB。 分享一个Lua语言的中文pdf文档,有书签的,里面还有lua的运行环境,希望更多的人可以来学习Lua这一优美小巧的语言...
Lua实现OOP,可以继承,覆盖,sample里面实现了简单的lua类定义,并封装了简单的事件驱动机制
Lua中文教程,高清PDF文档,官方发布
解析Lua实现方法 解析Lua实现方法
资源为lua语言调用jwt实现token验证的源文件,里面文件包括四个文件: evp.lua hmac.lua jwt-validators.lua jwt.lua 在你使用openresty的时候,需要调用jwt进行token操作,需要将这个四个文件拷贝到/usr/local/...
MVVM源于MVC(Model-View-Controller)模式,...MVVM本质就是基于操作数据来操作视图进而操作DOM,借助于MVVM无需直接操作DOM,开发者只需完成包含声明绑定的视图模板,编写ViewModel中有业务,使得View完全实现自动化。