Lua中调用C语言函数实例_Lua

在上一篇文章(C调用lua函数)中,讲述了如何用c语言调用lua函数,通常,A语言能调用B语言,反过来也是成立的。正如Java与c语言之间使用JNI来互调,Lua与C也可以互调。

当lua调用c函数时,使用了和c调用lua中的同一种栈,c函数从栈中得到函数,然后将结果压入栈中。为了区分返回结果和栈中的其他值,每一个函数返回结果的个数。
这里有个重要的概念:这个栈不是全局的结构,每个函数都有自己的私有局部栈。哪怕c函数调用了lua代码,lua代码再次调用该c函数,他们有各自独立的局部栈。第一个参数的索引是1。
作为第一个例子,让我们看看如何实现一个简单的函数,返回给定2个参数的和:

复制代码 代码如下:

static int l_plus(lua_State* L)
{
     lua_Integer a = lua_tointeger(L, 1);
     lua_Integer b = lua_tointeger(L, 2);
     lua_pushinteger(L, a+b);
     return 1;
}

每一个Lua注册的函数都必须是这个原型,它已经在lua.h中定义了:

复制代码 代码如下:

typedef int (*lua_CFunction) (lua_State *L);

由于c函数返回了一个int类型的返回值个数。因此,当压入返回值之前,不必要清理栈,lua会自动移除返回值下面的任何数据。

在lua中使用该函数之前,我们需要注册它。使用lua_pushcfunction,它接受一个c函数,然后在lua内部创建一个函数类型的值来表示该函数。

复制代码 代码如下:

lua_pushcfunction(L, lua_plus);
lua_setglobal(L, "myplus");

一个专业点的写法是,我们必须检查它的参数类型:

复制代码 代码如下:

static int l_plus(lua_State* L)
{
     lua_Integer a = luaL_checkinteger(L, 1);
     lua_Integer b = luaL_checkinteger(L, 2);
     lua_pushinteger(L, a+b);
     return 1;
}

完整代码:

复制代码 代码如下:

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
static int l_plus(lua_State* L)
{
     lua_Integer a = luaL_checkinteger(L, 1);
     lua_Integer b = luaL_checkinteger(L, 2);
     lua_pushinteger(L, a+b);
     return 1;
}

int main()
{
     lua_State *L = luaL_newstate();
     luaL_openlibs(L);
     lua_pushcfunction(L, l_plus);
     lua_setglobal(L, "myplus");
     if (luaL_dostring(L, "print(myplus(2,2))")) {
          lua_close(L);
          error("Failed to invoke");
     }
     lua_close(L);
     return 0;
}

(完)

时间: 2024-08-30 03:38:51

Lua中调用C语言函数实例_Lua的相关文章

Lua教程(四):在Lua中调用C语言、C++的函数_Lua

本教程将介绍如何在Lua里面调用c/c++函数. 在Lua里面调用c/c++函数其实是比较简单,本文将通过两个示例演示具体的做法:一个是求平均数,另一个是打印lua函数的一些参数信息. 最后,本文会介绍如何把这两个函数定义成一个模块,这样lua代码里面就可以不再使用全局的名字空间了. 前言 当我们需要在Lua里面调用c/c++函数时,所有的函数都必须满足以下函数签名: 复制代码 代码如下: typedef int (*lua_CFunction) (lua_State *L); 换句话说,所有的

Lua中的__index和__newindex实例_Lua

前言 这篇博文将通过几个简单的实例演示,巩固对__index和__newindex的理解,同时加深对Lua中元表和元方法的理解,如果对Lua的元表和元方法还不是很熟悉的话,请参考这篇文章:<Lua中的元表与元方法>. 具有默认值的table 我们都知道,table中的任何字段的默认值都是nil,但是通过元表,我们可以很容易的修改这一规定,代码如下: 复制代码 代码如下: function setDefault(tb, defaultValue)      local mt = {__index

Lua中的类编程代码实例_Lua

Lua的类有点像javascript,但是更简明灵活,table即对象,对象就是类.Metatables比起ruby里的MetaClass更加好用,缺点是实例化和继承的代码有点多, 不像ruby里的"<"和"<<",继承链就是查找方法时的方法链. Account={ test1=function(a) print("Account test1") end } Account.test2=function(a) print(&qu

Lua中使用二维数组实例_Lua

在Lua中跟JS也是一样,没有二维数组的概念,但是二维数组对我们的开发又是极其的重要,当然,使用很多啦.谈谈在Lua中如何使用二维数组? 原理,一维数组里面给一个嵌套就是二维数组了,好,就那么简单,看看代码更容易理解 最近在做一个项目,如下是部分代码 for i=1,10 do self.startMartix[i]={} self.star[i]={} for j=1,10 do self.startMartix[i][j]= starSprite self.star[i][j]=star_

Lua中简单的错误处理实例_Lua

昨天遇到另外一位独立游戏开发者,所以多聊了一会,然后-然后就没有看书了.(小若:借口!借口!)   今天来聊聊错误处理吧,不过毕竟这只是前面的章节,书上的内容似乎有点一笔带过的味道. 没关系,简单更好~ 1.红色警报--error 我们应该能经常看到类似以下的错误信息: 复制代码 代码如下: [LUA-print] LUA ERROR: [string "src/main.lua"]:108: [string "src/main.lua"]:89: attempt

Lua中遍历文件操作代码实例_Lua

写的一个关于遍历文件的程序段  记录一下咯 --[[检查所有.txt文件 比如A.txt中第一行规定有20列,但是在X行中多输入一个Tab,则输出:A表的X行填写不规范,行末有多余填写 ]] getinfo = io.popen('dir ..//file /b /s') all = getinfo:read('*all') local filenameList = io.open("filename.txt", "wb") filenameList:write(&

C++中调用Lua函数实例_Lua

唉,今天心情有点糟糕,我就少说一些啰嗦的话了. (旁白:太好了-) 上一章传送门:http://www.jb51.net/article/55096.htm 经过前面几章的介绍,相信大家对Lua的堆栈已经比较熟悉了,如果还不是很熟悉的朋友,建议多看几遍前面的教程,或者多敲几次代码. 那么,如果已经对Lua的堆栈比较熟悉,接下来的内容就很简单了. 今天我们来看看C++如何调用Lua的函数,先看看现在Lua文件是什么样的: 复制代码 代码如下: -- helloLua.lua文件 myName =

Lua中调用C++函数实例_Lua

到这为止,大家对Lua和C++之间的通信应该有些熟悉了,今天我们来介绍最后一个操作. (旁白:什么?最后一个?要结束了么?太好了~!) 上一章传送门:http://www.jb51.net/article/55097.htm 1. Lua调用C++的函数 Lua要调用C++的函数还是蛮方便的,首先,我们来创建一个c++函数先: 复制代码 代码如下: public: static int getNumber(int num); int HelloLua::getNumber( int num )

Lua中使用二维数组实例

  这篇文章主要介绍了Lua中使用二维数组实例,本文直接给出代码实例,看代码更容易理解,需要的朋友可以参考下 在Lua中跟JS也是一样,没有二维数组的概念,但是二维数组对我们的开发又是极其的重要,当然,使用很多啦.谈谈在Lua中如何使用二维数组? 原理,一维数组里面给一个嵌套就是二维数组了,好,就那么简单,看看代码更容易理解 最近在做一个项目,如下是部分代码 ? 1 2 3 4 5 6 7 8 for i=1,10 do self.startMartix[i]={} self.star[i]={