Lua怎么和字符串指针兼容
解决时间 2021-05-08 06:11
- 提问者网友:放下
- 2021-05-07 13:36
我写了一个C函数
function(char * buffer, int nLen)
{
strcpy(buffer,"asjfla");
return strlen(buffer);
}
在lua中怎样调用function呢??
最佳答案
- 五星知识达人网友:掌灯师
- 2021-05-07 14:22
扩展Lua的基本方法之一就是为应用程序注册新的C函数到Lua中去。
当我们提到Lua可以调用C函数,不是指Lua可以调用任何类型的C函数(有一些包可以让Lua调用任意的C函数,但缺乏便捷和健壮性)。正如我们前面所看到的,当C调用Lua函数的时候,必须遵循一些简单的协议来传递参数和获取返回结果。相似的,从Lua中调用C函数,也必须遵循一些协议来传递参数和获得返回结果。另外,从Lua调用C函数我们必须注册函数,也就是说,我们必须把C函数的地址以一个适当的方式传递给Lua解释器。
当Lua调用C函数的时候,使用和C调用Lua相同类型的栈来交互。C函数从栈中获取她的参数,调用结束后将返回结果放到栈中。为了区分返回结果和栈中的其他的值,每个C函数还会返回结果的个数(the function returns (in C) the number of results it is leaving on the stack.)。这儿有一个重要的概念:用来交互的栈不是全局变量,每一个函数都有他自己的私有栈。当Lua调用C函数的时候,第一个参数总是在这个私有栈的index=1的位置。甚至当一个C函数调用Lua代码(Lua代码调用同一个C函数或者其他的C函数),每一个C函数都有自己的独立的私有栈,并且第一个参数在index=1的位置。
26.1 C 函数
先看一个简单的例子,如何实现一个简单的函数返回给定数值的sin值(更专业的实现应该检查他的参数是否为一个数字):
static int l_sin (lua_State *L) {
double d = lua_tonumber(L, 1);
lua_pushnumber(L, sin(d));
return 1;
}
任何在Lua中注册的函数必须有同样的原型,这个原型声明定义就是lua.h中的lua_CFunction:
typedef int (*lua_CFunction) (lua_State *L);
从C的角度来看,一个C函数接受单一的参数Lua state,返回一个表示返回值个数的数字。所以,函数在将返回值入栈之前不需要清理栈,函数返回之后,Lua自动的清除栈中返回结果下面的所有内容。
我们要想在Lua使用这个函数,还必须首先注册这个函数。我们使用lua_pushcfunction来完成这个任务:他获取指向C函数的指针,并在Lua中创建一个function类型的值来表示这个函数。一个quick-and-dirty的解决方案是将这段代码直接放到lua.c文件中,并在调用lua_open后面适当的位置加上下面两行:
lua_pushcfunction(l, l_sin);
lua_setglobal(l, "mysin");
第一行将类型为function的值入栈,第二行将function赋值给全局变量mysin。这样修改之后,重新编译Lua,你就可以在你的Lua程序中使用新的mysin函数了。在下面一节,我们将讨论以比较好的方法将新的C函数添加到Lua中去。
对于稍微专业点的sin函数,我们必须检查sin的参数的类型。有一个辅助库中的luaL_checknumber函数可以检查给定的参数是否为数字:当有错误发生的时候,将抛出一个错误信息;否则返回作为参数的那个数字。将上面我们的函数稍作修改:
static int l_sin (lua_State *L) {
double d = luaL_checknumber(L, 1);
lua_pushnumber(L, sin(d));
return 1;
}
根据上面的定义,如果你调用mysin('a'),会得到如下信息:
bad argument #1 to 'mysin' (number expected, got string)
注意看看luaL_checknumber是如何自动使用:参数number(1),函数名("mysin"),期望的参数类型("number"),实际的参数类型("string")
我要举报
大家都在看
推荐资讯