Lua学习笔记二

转载 2013年12月05日 19:36:18

Lua学习笔记二
在Lua中使用自己的C函数

 


 

OK,上次我们掌握了如何在Lua脚本中编写一个函数,并在C文件中接应它。
现在让我们来学习另外一种交互方式。

本节的目的:在Lua脚本中调用自己写的函数。侧重点为自己编写可以被Lua脚本使用的C函数的规则。

 


 啥都不说了,RTFS

 

-------以下是Lua脚本--------
--test.lua
LuaC_MessageBox( "Last is ShowMessage! This is real MessageBox!");
---------通过LuaEdit语法测试才出鬼了--------------

//------------以下是test.cpp文件----------------
//================================================================================================================
//           Lua Test Object
//           C++ Source lua_test.cpp
//================================================================================================================
//================================================================================================================
//           Include Files
//================================================================================================================
extern "C"
{
 #include "D://My Documents//Visual Studio 2005//Projects//lua//lua//lua.h"
 #include "D://My Documents//Visual Studio 2005//Projects//lua//lua//lualib.h"
 #include "D://My Documents//Visual Studio 2005//Projects//lua//lua//lauxlib.h"
}

#include <windows.h>
#include <stdio.h>
#include <string>
using namespace std;
//================================================================================================================
//           Libraries
//================================================================================================================
#pragma comment( lib ,"D://My Documents//Visual Studio 2005//Projects//lua//release//lua.lib")
//================================================================================================================
//           Global Variables
//================================================================================================================
lua_State *L;
//================================================================================================================
//           Lua Functions
//================================================================================================================
double f( double x, double y )
{
 double ret;
 lua_getglobal( L, "f");
 lua_pushnumber( L,x);
 lua_pushnumber( L,y);
 lua_call( L, 2, 1);
 //lua_pcall( L, 2, 1, 0);

 ret = lua_tonumber( L, -1);
 //lua_pop( L, 1);
 return ret;
}
//================================================================================================================
//           C/C++ Functions
//================================================================================================================
int LuaC_MessageBox( lua_State *L)
{
 char Message[256] = "";
 int i;

 // 获取参数个数
 int n = lua_gettop(L);

 // 保存全部参数
 for ( i = 1, j = 0; i <= n ; i++)
 {
  if( lua_isstring( L, i))
   strcpy( Message, lua_tostring( L, i));
 }

 // 执行逻辑
 MessageBox( NULL, Message, "Lua Test", MB_OK );

 // 返回值压栈

 // 返回压栈参数的个数
 return 0;
}
//================================================================================================================
//           Main Functions
//================================================================================================================
int main( void)
{
 int error;

 L = lua_open();
 luaopen_base(L);
 luaL_openlibs(L);

  // 注册C/C++函数
  lua_register( L, "LuaC_MessageBox", LuaC_MessageBox);



// load the script 
// 加入了错误处理
 if ( (error = luaL_dofile(L, "test.lua")) != 0)
 {
  MessageBox( NULL, "出错啦:执行脚本出错!", "Lua Test", MB_OK );
  return 0;
 }

 
 getchar();
 lua_close( L);
 return 1;
}

 


 

额....这就是系列文章的好处:即使CSDN把原来的弄丢了,我也可以根据上下文来重写丢失的文章。

如你所见,我将关键点全部标记为粗体。并且给出了足够的注释。让我们来一条条梳理:

1、LuaC_MessageBox( "Last is ShowMessage! This is real MessageBox!");
这就是Lua脚本调用自己写的函数。让我们接着看如何实现这个函数的。

2、int LuaC_MessageBox( lua_State *L)
这个就是函数的实体了,要想使自己的函数被Lua脚本所用,必须遵守以下规则:
        使用 int 函数名( lua_State *L) 的形式来声明和定义函数。
        使用Lua的堆栈来进行参数交换。
        调用Lua的注册函数。

3、关于第2个规则,Lua是按照  __fastcall 的规则传递参数的,也就是从左到右一个个传。
Lua压栈的顺序是:首先将函数压栈,然后将参数压栈。执行完毕后,将参数和函数都出栈,然后将返回值按顺序压栈。当然,还有很多类似的参数交换规则,不过别急我们慢慢来。

4、retrun 0;
在C函数中的返回值 指的是返回值的数量。因为Lua脚本是支持多个返回值的,结合上条和这条规则来实现。

5、C文件中的函数体编写完了,还需要将该函数进行注册,如:
lua_register( L, "LuaC_MessageBox", LuaC_MessageBox);
第二个参数为Lua脚本中的函数名,第三个为C文件中的函数名。

6、还有什么是我没涉及到的?返回值压栈!但是我想暂时不谈这个问题,因为我将(已经)在笔记四中详细讨论。所以,先熟悉这个基本流程。

7、OK。重写的好处在于:我可以直接把笔记四的东西搬过来。哈哈,又一次时间旅行。
Lua中有很多把各类返回值压栈的函数,只要你在Lua参考手册中搜索“lua_push”,你可以得到如下结果:
lua_pushboolean
lua_pushinteger
lua_pushfstring
lua_pushlstring
lua_pushnil
lua_pushnumber
.....
有很多这样的函数,解释可以参看参考手册(一定要看!)。
但是在这个例子中,我们没有返回值,所以retrun 0。

相关文章推荐

lua学习笔记

  • 2014年03月05日 11:15
  • 13KB
  • 下载

lua学习笔记(二)

一、深入lua函数 一些必要的概念: 参考自:https://www.douban.com/note/183992679/?type=rec#sep http://en.wikipedia.or...

Lua 学习笔记(二) —— Scite 的配置文件讲解

Scite的配置文件ru SciTEGlobal.properties 全局配置文件,一般不去改动 SciTEUser.properties 用户配置文件,对全局配置要改动的地方,都写在这个文...

Lua学习笔记(二)

1.type函数总是返回一个字符串,因此    print(type(type(x)))    的输出结果是string 2.函数是作为"第一类值"来看待的,可以像操作其他值一样来操作一个函数值 3....
  • zzh0923
  • zzh0923
  • 2013年10月15日 15:48
  • 968

lua 学习笔记 二

11.0 lua中的习惯一般是以1作为数组的起始索引,lua库和长度操作符都遵循这个约定。 对于稀疏矩阵,存在大量的“空洞(nil值)”,遍历矩阵的效率很低,通常使用pairs且只遍历非nil元素...

lua学习笔记二--函数

lua学习笔记,函数,以及函数参数和多重赋值的特性

Lua学习笔记二 数据类型及字符串操作

基本用法 读取 Properties properties=new Properties(); try{ FileInpu...
  • xundh
  • xundh
  • 2015年06月05日 10:02
  • 405

Lua 学习笔记(二)

函数这一章我们介绍一下lua中函数的声明,其实函数这东西我们每个人都接触过,就像我们初中高中学的一次函数 ,二次函数是一样的。举个简单的例子吧,目前欧元汇率和人民币汇率的比例是1欧元换7.2人民币,那...

Lua学习笔记(基础二)

四、表达式 1、算数操作符       除了基本的“+ - * /”,Lua中特殊的在于“^”表示指数运算;“%”取模可用于任何实数(而非C中仅限整型)。 a=8^(1/3) --计算8的1/3...

Lua 学习笔记(四) —— 函数(二)

一、函数是匿名的 函数是匿名的是指它没有名称。 一个函数定义实际就是一条语句(更准确地说是一条赋值语句),这条语句创建了一种类型为“函数”的值,并将这个值赋予一个变量。例如,讨论print函数时,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Lua学习笔记二
举报原因:
原因补充:

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