从Lua调用C

Posted zhchoutai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从Lua调用C相关的知识,希望对你有一定的参考价值。

从Lua调用C:
方式:C函数从栈中获取函数參数(第一个參数总是局部栈的索引1),将结果压入栈中,C函数须要返回结果数量。

每一个函数都有自己的局部私有栈


样例:
static int l_sin(lua_State *L){
	double d = lua_tonumber(L,1);	//获取參数,索引为1(私有栈)
	lua_pushnumber(L,sin(d));		//压入结果
	return 1;						//返回结果的数量
}




注冊函数到Lua:
1、函数的原型: typedef int(*lua_CFunction)(lua_State *L)
在函数返回之前,Lua会自己主动删除栈中结果之下的内容


2、使用lua_pushcfunction(L,func)
lua_setglobal(L,"mysin")
3、參数类型检查:将lua_tonumber(L,1)改成luaL_checknumber(L,1)


注冊函数模块:
luaL_register:这个函数接收一些C函数及其名称,并将这些函数注冊到一个与模块同名的table中。
样例:
C:
static const struct luaL_Reg mylib[] = {
	{"dir",l_dir},
	{NULL,NULL}	//结尾
}
luaL_register(L,"mylib",mylib);


Lua:
require "mylib"
print("mylib.mysin(10)",mylib.mysin(10))

数组操作:


void lua_rawgeti(lua_State* L,int index,int key)
void lua_rawset(L,index,key)


lua_rawgeti(L,t,key)等价于:
lua_pushnumber(L,key)
lua_rawget(L,t)


lua_rawget类似于lua_gettable,差别在于raw能够绕过元表的index


lua_rawseti(L,t,key)等价于:
lua_pushnumber(L,key)
lua_insert(L,-2) //将‘key‘放到前一个值的以下:由于rawset的规则是key在以下value在栈顶
lua_rawset(L,t)


这两个函数都是raw操作,比涉及元表的table訪问更快。
演示样例:
int l_map(lua_State *L){
	int i,n;


	luaL_checktype(L,1,LUA_TTABLE);	//第一个參数必须是一个table
	luaL_checktype(L,2,LUA_TFUNCTION);	//第二个參数必须是一个函数


	n = lua_objlen(L,1);		//获取table大小
	for(int i=1;i<=n;i++){
		lua_pushvalue(L,2);		//压入f
		lua_rawgeti(L,1,i);		//压入t[i]
		lua_call(L,1,1);		//调用f(t[i])
		lua_rawseti(L,1,i);		//t[i] = 结果,***rawseti设置后会清除栈顶的返回值
	}
	
	return 0;
}


以上是关于从Lua调用C的主要内容,如果未能解决你的问题,请参考以下文章

快速掌握Lua 5.3 —— 从Lua中调用C函数

从Lua调用C

从lua的c源码了解lua栈结构和函数调用流程

lua 与 c++或者c 交互的底层原理谁能解释一下?最最底层的,为啥它们调用C或者C++的函数?

lua调用C语言

Lua与C/C++交互——C/C++调用Lua脚本