第一步是定义函数。所有在Lua中被调用的C/C++函数将使用下面一类指针进行调用:

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

换句话说,函数必须要以Lua解释器作为唯一的参数,并且返回一个唯一的整数。由于用一个Lua解释器作为参数,因此函数实际上能够从栈中取得任意数量的参数。

在后面我们将看到,返回的整数实际上是被压入栈的值的个数。通过如此容易的封装,就能满足你在Lua中调用C++函数的需求。

下面给出的C++函数average()演示了如何接受多个参数且返回超过一个值。记住,该函数是一个与上面typedef相匹配的函数:

#include "stdafx.h"
#include <stdio.h> extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
static int average(lua_State *L)
{
/* 得到参数个数 */
int n = lua_gettop(L);
double sum = ;
int i; /* 循环求参数之和 */
for (i = ; i <= n; i++)
{
/* 求和 */
sum += lua_tonumber(L, i);
} /* 压入平均值 */
lua_pushnumber(L, sum / n); /* 压入和 */
lua_pushnumber(L, sum); /* 返回返回值的个数 */
return ;
} /* 指向Lua解释器的指针 */
int lua_call_cpp( int argc, char *argv[] )
{
/* 初始化Lua */
//L = lua_open();
lua_State* L = luaL_newstate(); /* 载入Lua基本库 */
luaL_openlibs(L); /* 注册函数 */
lua_register(L, "average", average); /* 运行脚本 */
luaL_dofile(L, "avg.lua"); /* 清除Lua */
lua_close(L); /* 暂停 */
printf( "Press enter to exit…" );
getchar();
return ;
}

保存文件为lua_avg.cpp。如果你直接使用C而不是C++,将文件名改为luaavg.c,然后将extern "C"删除。

代码解释:

  1. lua_gettop函数返回栈顶的索引值。因为在Lua中栈是从1开始编号的,因此该函数获得的值就是参数的个数。
  2. 在for循环中计算所有参数之和。
  3. 调用lua_pushnumber()将参数的平均值压栈。
  4. 将参数之和压入栈中。
  5. 最后,函数返回2,说明有两个返回值在栈中。

编译

在Linux下,在命令行键入:

g++ luaavg.cpp -llua -llualib -o luaavg

然后,键入下列命令运行:

./luaavg

如果没有问题, 程序将显示出平均值、和。

在Visual C++你将需要进行下列步骤:

  1. 创建一个新的空Win32控制台应用工程。
  2. 将"lua_call_cpp.cpp"加入你的工程。
  3. 选择项目菜单中的属性菜单。
  4. 在"连接器"的"输入"栏目的"附加依赖项"中输入"lua5.2.3.lib"。

此时,按F7构建程序。

如果你采用的是dll库,请确保将其放在应用程序的目录中或者windows系统能够找到它的地方。如果你采用的是静态连接库,则不需要。

错误处理

如果你已经阅读了Lua的API文档,你将看出实际上我上面的average函数没有进行错误检查。

然而在真实的程序中你应该做一些错误检测。在上面的例子中,我们至少应该检查每个参数是不是数字。

通过在for循环中添加下面的代码来实现:

if (!lua_isnumber(L, i)) {

        lua_pushstring(L, "Incorrect argument to 'average'");

           lua_error(L);

}
添加这样的检查很容易,同时这样也让调试更容易。当处理用两种不同语言编写的程序的时候,这显得相当重要;

原文: http://blog.csdn.net/Lodger007/article/details/837349

lua如何调用C++函数的更多相关文章

  1. Lua中调用C函数

    Lua利用一个虚拟的堆栈来给C传递值或从C获取值.每当Lua调用C函数,都会获得一个新的堆栈,该堆栈初始包含所有的调用C函数所需要的参数值(Lua传给C函数的调用实参),并且C函数执行完毕后,会把返回 ...

  2. Lua中调用C函数(lua-5.2.3)

    Lua能够调用C函数的能力将极大的提高Lua的可扩展性和可用性. 对于有些和操作系统相关的功能,或者是对效率要求较高的模块,我们全然能够通过C函数来实现,之后再通过Lua调用指定的C函数. 对于那些可 ...

  3. lua中调用C++函数

    lua中调用C++函数 我们产品中提供了很多lua-C API给用户在lua中调用,之前一直没用深究其实现原理,只是根据已有的代码在编码.显然这不是一个好的习惯,没用达到知其所以然的目的. 一.基本原 ...

  4. cocos2dx中使用tolua++使lua调用c++函数

    一直想学学cocos2dx中如何使用tolua++工具使得lua脚本调用C++函数,今天就来搞一下,顺便记录下来: 首先,我们打开cocos2dx-2.2.4中projects下的test的VS工程, ...

  5. Step By Step(Lua调用C函数)

    原文: http://www.cnblogs.com/stephen-liu74/archive/2012/07/23/2469902.html Lua可以调用C函数的能力将极大的提高Lua的可扩展性 ...

  6. cocos2d-x 2.2.0 如何在lua中注册回调函数给C++

    cocos2d-x内部使用tolua进行lua绑定,但是引擎并没有提供一个通用的接口让我们可以把一个lua函数注册给C++层面的回调事件.翻看引擎的lua绑定代码,我们可以仿照引擎中的方法来做.值得吐 ...

  7. cocos2d-x 2.2.0 怎样在lua中注冊回调函数给C++

    cocos2d-x内部使用tolua进行lua绑定.可是引擎并没有提供一个通用的接口让我们能够把一个lua函数注冊给C++层面的回调事件. 翻看引擎的lua绑定代码,我们能够仿照引擎中的方法来做. 值 ...

  8. 深入xLua实现原理之Lua如何调用C#

    xLua是腾讯的一个开源项目,为Unity. .Net. Mono等C#环境增加Lua脚本编程的能力.本文主要是探讨xLua下Lua调用C#的实现原理. Lua与C#数据通信机制 无论是Lua调用C# ...

  9. [置顶] lua 进阶3--lua文件中调用C++函数

    前面讲了一下,C++读取lua文件中的变量,包括一维表.二维表这些,这节讲一下如何在lua文件中去调用C++函数 C++代码如下 #include <stdio.h> extern &qu ...

随机推荐

  1. 8421BCD码转换为十进制

    这个转换和随意的认知是不同的,要了解BCD码和二进制码的区别 #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) ...

  2. Lessons Learned 1(敏捷项目中的变更影响分析)

    问题/现象: 业务信息流转的某些环节,会向相关人员发送通知邮件,邮件中附带有链接,供相关人员进入察看或处理业务.客户要求邮件中的链接,需要进行限制,只有特定人员才能进入处理或察看.总管想了想,应道没问 ...

  3. CSS有三种基本的定位机制

    CSS有三种基本的定位机制:普通流,浮动和绝对定位. 普通流:在普通流中元素框的位置由元素在html中的位置决定, 1.元素position属性为static或继承来的static时就会按照普通流定位 ...

  4. 1813. M进制数问题

    1813. M进制数问题 Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description 试用 C++的类来表示一般进制数. 给定 2 ...

  5. 小JAVA大世界之程序建模跳蚤实验

    package com.chigoe;//房子类class House { private int m;// 保存行数 private int n;// 保存列数 private int[][] a; ...

  6. 【洛谷P3197】越狱

    本来还想了一会dp-- 然而一看数据范围明显是数论-- 那么推一推.. 我们发现可以用总方案数减去不会越狱的方案数 那么我们考虑在长度为n的数列中填数 首先第一个位置有m种选择,后面的位置: 总方案: ...

  7. 区间型DP

    区间型DP是一类经典的动态规划问题,主要特征是可以先将大区间拆分成小区间求解最后由小区间的解得到大区间的解. 有三道例题 一.石子合并 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆. ...

  8. Sprint评审会议不是Sprint演示会议

    最近,Innolution公司的执行总监.Essential Scrum的作者Ken Rubin在其公司博客上撰写了一篇题为It’s a Sprint Review Not a Sprint Demo ...

  9. [ImportNew] Perforce - Restoring Mistakenly Deleted Files in Workspace

    Shit happens when you accidentally delete some files in your workspace and you have no ideas which o ...

  10. iOS 笔记

    1. 使用断言NSAssert()调试程序错误 NSAssert()只是一个宏,用于开发阶段调试程序中的Bug,通过为NSAssert()传递条件表达式来断定是否属于Bug,满足条件返回真值,程序继续 ...