lua要调用的C函数有一个一致的签名:
typedef int (*lua_CFunction) (lua_State *L);
函数的返回值表示函数的返回值个数,lua与C通过lua虚拟机中的栈来传递参数和返回参数。
即C中的函数应该定义为:
int testfunc(lua_State* L)
{
printf("testfunc from C");
return 0;
}
return 0:表示函数没有返回值。
简单的例子CC代码:
int main()
{
lua_State* L = luaL_newstate(); /* create state */
if (L == NULL) {
printf("lua state build error.\n");
return 1;
}
luaL_openlibs(L);
lua_pushcfunction(L, testfunc);
lua_setglobal(L, "testfunc");
luaL_dofile(L, "tfunc.lua");
std::cin.get();
lua_close(L);
return 0;
}
简单的例子lua代码:
print("print from tfunc lua.")
testfunc()
下面以sum函数为例子来说明lua中调用C函数有多个参数和多个返回的情况:
lua代码为:
print("print from tfunc lua.")
testfunc()
total, avg = sum(1,2,3,4,5)
print(total, avg)
CC代码为:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include "lua.hpp"
#include "lauxlib.h"
#include "lualib.h"
static void stackDump(lua_State* L)
{
static int count = 0;
printf("begin dump lua stack:%d\n", count);
int top = lua_gettop(L);
for (int i = top; i > 0; --i)
{
int t = lua_type(L, i);
switch (t)
{
case LUA_TSTRING:
printf("%s\n", lua_tostring(L, i));
break;
case LUA_TBOOLEAN:
printf(lua_toboolean(L, i) ? "true\n" : "false\n");
break;
case LUA_TNUMBER:
printf("%g\n", lua_tonumber(L, i));
break;
default:
printf("%s\n", lua_typename(L, t));
break;
}
}
++count;
}
int testfunc(lua_State* L)
{
printf("testfunc from C");
return 0;
}
int sum(lua_State* L)
{
//lua中传过来的参数在栈中,我们可以从栈顶到栈底打印一下内容
stackDump(L);
int total = 0;
int n = lua_gettop(L);
for (int i = n; i > 0; --i)
{
total += lua_tointeger(L, i);
}
//通过栈将返回传回lua
lua_pushinteger(L, total);
lua_pushinteger(L, total / n);
return 2; // 返回2个参数
}
int main()
{
lua_State* L = luaL_newstate(); /* create state */
if (L == NULL) {
printf("lua state build error.\n");
return 1;
}
luaL_openlibs(L);
lua_pushcfunction(L, testfunc); //将函数压入栈
lua_setglobal(L, "testfunc"); //将函数调出栈,并赋值为testfunc
lua_pushcfunction(L, sum);
lua_setglobal(L, "sum");
luaL_dofile(L, "tfunc.lua");
std::cin.get();
lua_close(L);
return 0;
}