如何使用Lua扩展C/C++应用系列3

原创 2005年04月23日 10:35:00

作者:buxiu 转自:Lua中文网站(www.luachina.net)

这次与第二篇文章相反,介绍如何在Lua中调用C/C++函数,首先,我们用C/C++创建一个函数并告诉Lua解释器,然后在Lua中调用这个函数并使用函数的返回值。
定义一个C/C++函数:
要想C/C++中的函数能被Lua调用,函数定义必须这样:

代码:
typedef int (*lua_CFunction) (lua_State *L);

也就是说,函数必须以Lua解释器作为参数,并且返回值为int类型。既然Lua解释器作为函数的参数,那么实际上函数可以从栈中取得任意多个参数。下面我们将看到,返回的整数值代表入栈的值的数目。如果有一个C/C++函数,你想在Lua中调用他,很容易封装一下就可以满足上述要求。
下面的C++的average函数例子中,可以清楚地看到Lua中调用C/C++函数是如何实现的。
1. lua_gettop()返回栈顶的下标索引,由于Lua中栈的下标从1开始,这个返回值实际上也就是函数参数的个数。
2. For循环计算各个参数总和。
3. Average的参数是通过调用lua_pushnumber()入栈的。
4. 然后参数之和被入栈。
5. 最后,函数返回值为2,表明有两个返回值,并且已经入栈。
函数被定义之后,我们必须告诉Lua编译器他的存在,这在main()函数中,在Lua解释器被初始化,类库加载之后完成的。
将下面的代码保存为luaavg.cpp,如果你喜欢用C而不是C++,需要保存文件为luatest.c并且把extern去掉。
代码:
#include <stdio.h>

extern "C" {
    #include "lua.h"
    #include "lualib.h"
    #include "lauxlib.h"
}

/* the Lua interpreter */
lua_State* L;

static int average(lua_State *L)
{
    /* get number of arguments */
    int n = lua_gettop(L);
    double sum = 0;
    int i;

    /* loop through each argument */
    for (i = 1; i <= n; i++)
    {
        /* total the arguments */
        sum += lua_tonumber(L, i);
    }

    /* push the average */
    lua_pushnumber(L, sum / n);

    /* push the sum */
    lua_pushnumber(L, sum);

    /* return the number of results */
    return 2;
}

int main ( int argc, char *argv[] )
{
    /* initialize Lua */
    L = lua_open();

    /* load Lua base libraries */
    lua_baselibopen(L);

    /* register our function */
    lua_register(L, "average", average);

    /* run the script */
    lua_dofile(L, "avg.lua");

    /* cleanup Lua */
    lua_close(L);

    return 0;
}

一个简单的Lua脚本,调用C/C++函数,并打印其返回值,保存为avg.lua:
代码:
-- call a C++ function

avg, sum = average(10, 20, 30, 40, 50)

print("The average is ", avg)
print("The sum is ", sum)

编译:
Linux平台,键入命令:
代码:
g++ luaavg.cpp -llua -llualib -o luaavg

运行程序:
代码:
./ luaavg

如果正常的话程序应该显示:"The sum is 25"
如果你不是Linux操作系统,使用的是Vc++编译器,你需要:
1. 创建一个新的win32控制台应用工程。
2. 将文件luaavg.cpp添加到你的工程中。
3. 到Project, Settings点击Link页。
4. 添加lua+lib.lib到Object/library modules列表中。
5. 按F7编译程序。
运行程序以前,你需要确保lua+lib.dll文件放在windows可以找到的地方,将这个文件从C:/Program Files/Lua-5.0拷贝到Visual C++ project目录,如果编译没有错误的话,现在可以Ctrl+F5运行程序了。
关于错误处理:
如果你看过Lua API文档,你会发现在上面的average函数中并未进行参数检查,这样做的目的是为了更容易解释问题,但是在一个实际的程序中错误检查是必要的。在上面的例子中我们至少应该确保每一个参数是一个整数,可以用下面代码实现:
代码:
if (!lua_isnumber(L, i)) {
    lua_pushstring(L, "Incorrect argument to 'average'");
    lua_error(L);
}

这样易于以后的调试。在使用两种语言进行开发的时候这是非常重要的一点,否则你会发现你将陷于忙于两种语言之间进行调试。

手动使用C/C++编写Lua扩展插件

最近在研究如何在Windows 下嵌入Lua来完成业务模块编写的时候 发现Lua的一些问题,首先Lua作为一门脚本语言,其灵活性和可扩展性是很高的,要不然Cocos2d-x中也不会嵌入他来编写业务逻辑...
  • yue7603835
  • yue7603835
  • 2014年12月12日 02:04
  • 6072

如何使用Lua扩展C/C++应用系列1

作者:buxiu  转自:Lua中文网站(www.luachina.net)Lua是轻量级的脚本语言,可以很方便用来扩展C/C++应用程序,下面我们通过几个简单的例子来学习Lua如何扩展C/C++的。...
  • ouyangbuxiu
  • ouyangbuxiu
  • 2005年04月23日 10:32
  • 2462

如何使用Lua扩展C/C++应用系列2

作者:buxiu  转自:Lua中文网站(www.luachina.net)这一篇接着第一个篇"Hello, World!",介绍如何在Lua中定义函数然后在C/C++中调用他,这将涉及到参数传递,返...
  • ouyangbuxiu
  • ouyangbuxiu
  • 2005年04月23日 10:33
  • 2277

用C语言扩展lua模块(入门)

lua中常常加载一些模块来实现某些功能。如果没有现成的模块以供require,那么我们只好自己写模块了。   前几天用C给lua扩展了sha1算法模块。提炼出来做个笔记。   lua示例代码如下:...
  • weiyuefei
  • weiyuefei
  • 2016年07月28日 11:43
  • 1118

Lua与C——扩展Lua(四)

因为Lua是可扩展的,我们可以通过编写新的C函数来扩展Lua。 先编写C函数;int add(lua_State *L) { int num1 = lua_tonumber(L, 1); ...
  • X805433354
  • X805433354
  • 2015年06月15日 18:08
  • 572

对lua的简单扩展,使它能快速关联C++的数据。

很早的时候,我纠结过一件事,假如,我在C++公开给脚本的接口中,要使用C++里的某一个对象,并且,我的程序中有很多个不同的lua虚拟机,每一个虚拟机要关联一个C++对象,并且这是多线程的,那么这时候应...
  • Gnorth
  • Gnorth
  • 2014年08月16日 12:46
  • 1063

2045不容易系列之(3)—— LELE的RPG难题(递推)

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submissio...
  • qq_34594236
  • qq_34594236
  • 2016年06月29日 09:12
  • 248

C/C++ 与lua混合使用入门讲的比较好的文章

转载一篇将C/C++ 与lua混合使用入门讲的比较好的文章 转自 http://www.open-open.com/home/space-6246-do-blog-id-1426.html ...
  • linuxheik
  • linuxheik
  • 2016年11月18日 16:35
  • 1047

lua中如何加入第三方拓展c库

背景及需求 lua作为一门发展成熟的脚本语言,正在变得越来越流行。它也可以作为和C/C++执行脚本交互的语言。并且Lua的整个库很小,当Lua自身带有的部分库无法满足我们自身需要实现的功能时,我们就需...
  • q270274978
  • q270274978
  • 2014年12月20日 13:10
  • 3718

利用luabind从C++中传递指针到lua中,lua操作指针对象

(前提条件: 1.配置好lua环境 2.配置好boost库 3.编译好luabind 项目忙写的比较简单,详细使用可以QQ联系我545550598.主要功能是C++中传递一个指针到lua中,使...
  • dugaoda
  • dugaoda
  • 2015年12月16日 11:26
  • 1999
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:如何使用Lua扩展C/C++应用系列3
举报原因:
原因补充:

(最多只允许输入30个字)