`
836811384
  • 浏览: 551266 次
文章分类
社区版块
存档分类
最新评论

在lua中实现printf

 
阅读更多

本文讨论如何在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!




分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics