如何调试lua脚本

2024-05-15

1. 如何调试lua脚本

调试lua现有的几种方案:
 1)luaedit  : 编辑断点和断点命中查看那些都让习惯用vs的人感到亲切,但是它只是在纯lua环境下的编辑器,也就是说和期望程序运行中能借用它来调试脚本可能性不大(至少我没有试验出来),能用上的需要给lua脚本做个main脚本函数,并提供一系列伪的c api(由lua实现的函数,只提供制定值的返回)。由luaedit启动脚本main函数进行调试
 2)利用 lua debug 库中的 hook ,然后记录一张断点位置表,设置行模式的 hook ,每次进入 hook 都检查是否是断点处,若是就停下来等待交互调试。这个方法有效,但是很消耗 cpu 。因为每进入一个新的代码行,都需要回调一个函数。当这个函数本身又是用 lua 写的时候,效率更低。
 3)利用lua脚本函数实现,在lua脚本中封装一个断点函数,这种方式结合debug库实现断点和栈信息,然后利用lua环境下的表对函数调用信息进行记录和打印,需要脚本使用者显式提供断点函数的调用。这个办法的优点自己可以组合出适合自己项目的断点调试方案。但缺点是相对繁琐,而且断点命中以后难以和现有方式融合

如何调试lua脚本

2. 如何调试lua脚本

调试lua现有的几种方案:
 1)luaedit  : 编辑断点和断点命中查看那些都让习惯用vs的人感到亲切,但是它只是在纯lua环境下的编辑器,也就是说和期望程序运行中能借用它来调试脚本可能性不大(至少我没有试验出来),能用上的需要给lua脚本做个main脚本函数,并提供一系列伪的c api(由lua实现的函数,只提供制定值的返回)。由luaedit启动脚本main函数进行调试
 2)利用 lua debug 库中的 hook ,然后记录一张断点位置表,设置行模式的 hook ,每次进入 hook 都检查是否是断点处,若是就停下来等待交互调试。这个方法有效,但是很消耗 cpu 。因为每进入一个新的代码行,都需要回调一个函数。当这个函数本身又是用 lua 写的时候,效率更低。
 3)利用lua脚本函数实现,在lua脚本中封装一个断点函数,这种方式结合debug库实现断点和栈信息,然后利用lua环境下的表对函数调用信息进行记录和打印,需要脚本使用者显式提供断点函数的调用。这个办法的优点自己可以组合出适合自己项目的断点调试方案。但缺点是相对繁琐,而且断点命中以后难以和现有方式融合
望采纳

3. 怎么调试lua性能

调试lua现有的几种方案:
1)luaedit  : 编辑断点和断点命中查看那些都让习惯用vs的人感到亲切,但是它只是在纯lua环境下的编辑器,也就是说和期望程序运行中能借用它来调试脚本可能性不大(至少我没有试验出来),能用上的需要给lua脚本做个main脚本函数,并提供一系列伪的c api(由lua实现的函数,只提供制定值的返回)。由luaedit启动脚本main函数进行调试
2)利用 lua debug 库中的 hook ,然后记录一张断点位置表,设置行模式的 hook ,每次进入 hook 都检查是否是断点处,若是就停下来等待交互调试。这个方法有效,但是很消耗 cpu 。因为每进入一个新的代码行,都需要回调一个函数。当这个函数本身又是用 lua 写的时候,效率更低。
3)利用lua脚本函数实现,在lua脚本中封装一个断点函数,这种方式结合debug库实现断点和栈信息,然后利用lua环境下的表对函数调用信息进行记录和打印,需要脚本使用者显式提供断点函数的调用。这个办法的优点自己可以组合出适合自己项目的断点调试方案。但缺点是相对繁琐,而且断点命中以后难以和现有方式融合

怎么调试lua性能

4. lua脚本语言的概念解释?

Lua 教程
lua
Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Lua 是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组于 1993 年开发的,该小组成员有:Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo。
设计目的
其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Lua 特性
轻量级: 他用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。
可扩展: Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。
其它特性:
支持面向过程(procedure-oriented)编程和函数式编程(functional programming);
自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象;
语言内置模式匹配;闭包(closure);函数也可以看作一个值;提供多线程(协同进程,并非操作系统所支持的线程)支持;
通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等。
Lua 应用场景
游戏开发
独立应用脚本
Web 应用脚本
扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench
安全系统,如入侵检测系统
第一个 Lua 程序
接下来我们使用 Lua 来输出"Hello World!"
实例(Lua 5.3)
print("Hello World!")

5. 为什么将lua作为游戏脚本


为什么将lua作为游戏脚本

6. 如何在Java中使用Lua脚本语言

如何在Java中使用Lua脚本语言是本文要介绍的内容,主要是来学习LUA脚本语言在JAVA中如何来使用,Lua就不说了, 现在比较热门, 语法也很简单. 为了在Java中调用, 折腾了比较长的时间, 就把一些东西记在下面.来看详细内容讲解。
Lua是支持内嵌在C程序中的, 但是官方不支持Java. 在网上查了下, 有LuaJava开源库, 拿来试用了一下, 发现这个库还算比较完善的.  
 
这个LuaJava实际上就是按照Lua官方文档, 把Lua的C接口通过JNI包装成Java的库. 下载, 里面是一个.dll, 一个.jar. 把.dll放到java.library.path下, 再把.lib放到classpath中, helloworld运行OK.
但是, 测试的时候, 很快发现了第一个问题: 在调用LuaJava中提供的LuaState.pushInteger 方法的时候, 出现了错误 : Unsatisfied Link Error. 其他的LuaState.pushNumber方法倒是没有问题. 用Depends工具看了下, 这个.dll居然没有导出pushInteger这个函数. 晕....
下载LuaJava的源代码, 查看了下Luajava.c 和 Luajava.h, 发现果然里面有点问题, 在.h里面定义了JNI中对应Java函数的C函数
JNIEXPORT void JNICALL Java_org_keplerproject_luajava_LuaState__1pushInteger
但是.c中没有实现这个函数. 无语, 看来大马虎哪都有啊. 幸亏有源代码, 照猫画虎在Luajava.c中加上这个函数的实现,
JNIEXPORT void JNICALL Java_org_keplerproject_luajava_LuaState__1pushInteger     (JNIEnv * env, jobject jobj, jobject cptr, jint i)  {      lua_State * L = getStateFromCPtr( env , cptr );      lua_pushinteger(L, i);  } 

然后编译. 编译也出现了问题了, 官方文档中说可以用VC++来Build, 但是没有说官方用的是什么版本. 我用VC2005就不行. 好在Luajava比较小, 就一个.h 一个 .c , 在VC中新建一个.dll项目, 把文件加进去, 修改一下build参数 (Include 需要加上lua的头文件, lib中需要加上lua的.lib文件, 另外要选上 Compile as C Code (/TC) ) Build, 通过了.
这时再在Java中调用pushInteger方法就没有问题了.
在测试中, 发现Luajava提供的文档中, 对于Lua脚本怎么调用Java对象/方法很详细, 但是在Java中怎么调用Lua函数/取得返回值 就没有. 参考了http://www.lua.org/manual/5.1/manual.html#lua_CFunction 的Lua C文档, 实现了传递对象到Lua中并取得返回值的代码:
Test1: 测试传递简单类型, 并取得返回值:
Lua 脚本(test.lua):
function test(a,b)      return a+b  end 

Java代码:
static {          //加载Lua5.1.dll, 因为LuaJava最后还是要调用Lua的东西          System.loadLibrary("lua5.1");      }            public static void main(String[] argu) throws LuaException {                    LuaState L = LuaStateFactory.newLuaState();           L.openLibs();           //读入Lua脚本          int error = L.LdoFile("test.lua");          if (error != 0) {              System.out.println("Read/Parse lua file error. Exit.");              return;          }                     //找到函数test          L.getField(LuaState.LUA_GLOBALSINDEX, "test");          //参数1压栈          L.pushInteger(1);          //参数2压栈          L.pushInteger(2);          //调用!! 一共两个参数, 1个返回值          L.call(2, 1);          //保存返回值, 到a中          L.setField(LuaState.LUA_GLOBALSINDEX, "a");          //读入a          LuaObject l = L.getLuaObject("a");          //打印结果.          System.out.println("Result is " + l.getString());          L.close();  } 

测试2: 传递Java对象
class Value {      public int i;      public void inc() {          i++;      }      public int get() {          return i;      }      public String toString() {          return "Value is " + i;      }  } 

Lua脚本: (该脚本中调用两次对象的inc方法, 并调用get方法输出结果)
function test1(v)      v:inc();      v:inc();      print("In lua: " .. v:get());      return v  end 

Java 代码: (前面都一样, 略)
//找到函数test1  L.getField(LuaState.LUA_GLOBALSINDEX, "test1");  //生成新的对象供测试  Value v = new Value();  //对象压栈  L.pushObjectValue(v);  //调用函数test1, 此时1个参数, 1个返回值  L.call(1, 1);  //结果放在b中.  L.setField(LuaState.LUA_GLOBALSINDEX, "b");  LuaObject l = L.getLuaObject("b");  System.out.println("Result is " + l.getObject()); 

运行结果:
Result is Value is 2  In lua: 2 

和预期的一致.
实现一个怪物的创建,把lua里的设定当作初始状态传给monstor,名字为sample monstor,防御10,攻击10,生命100
1.先导入lib--luajava-1.1.jar
import org.keplerproject.luajava.LuaState;  import org.keplerproject.luajava.LuaStateFactory;   public class Load{  LuaState luaState;  /**  * Constructor  * @param fileName File name with Lua .  */  Load(final String fileName) {  this.luaState = LuaStateFactory.newLuaState();   this.luaState.openLibs();     this.luaState.LdoFile(fileName);   }  /**  * Ends the use of Lua environment.  */  void close() {  this.luaState.close();  }  /**  * Call a Lua inside the Lua to insert  * data into a Java object passed as parameter  * @param Name Name of Lua .  * @param obj A Java object.  */  void run(String Name, Object obj) {  this.luaState.getGlobal(Name);  this.luaState.pushJavaObject(obj);  this.luaState.call(1,0);  }  }   public class Monster{  /* Info */  protected String race;  protected int defense;  protected int attack;  protected int life;  /* */  private Load ;  public Monster(String race) {  /* Loads Lua for this race.*/  this. = new Load(race+".lua");  /*Call Lua create .*/  .run("create", this);  }   public void setRace(String race) {     this.race = race;  }  public String getRace() {  return race;  }  public int getDefense() {  return this.defense;  }  public void setDefense(int defense) {  this.defense = defense;  }  public int getLife() {  return this.life;  }  public void setLife(int life) {  this.life = life;  }  public void setAttack(int attack) {  this.attack = attack;  }  public int getAttack() {  return this.attack;  }  }   monstor.lua---   create(monster)  monster:setRace("Sample Monster")  monster:setDefense(10)  monster:setAttack(10)  monster:setLife(100)  end 

但总是抛出这个错误:
PANIC: unprotected error in call to Lua API (Invalid method call. No such method.) 

不知为何,以后用到的时候再research.
已经查出来,原来在Monster类中少了个方法:
public void setRace(String race) {     this.race = race;  } 

怪不得会找不到,
要在一lua文件a.lua里导入其他的lua文件b.lua,用require "b"
如果要从lua中运算后得到返回参数,则需要做一下修改:在lua文件中改成:
create(monster)  monster:setRace("Sample Monster")  monster:setDefense(10)  monster:setAttack(10)  monster:setLife(100)  return monster  end 

在Load.java中的run改成如下:
void run(String Name, Object obj) {     this.luaState.getGlobal(Name);     this.luaState.pushJavaObject(obj);     this.luaState.call(1, 1);// 一个参数,0个返回      try {      Object object =luaState.getObjectFromUserdata(1);     } catch (LuaException e) {      e.printStackTrace();     }  } 

转载仅供参考,版权属于原作者。祝你愉快,满意请采纳哦

7. 如何在Java中使用Lua脚本语言

LuaJava实际上就是按照Lua官方文档, 把Lua的C接口通过JNI包装成Java的库. 下载, 里面是一个.dll, 一个.jar. 把.dll放到java.library.path 下, 再把.lib放到classpath 中, helloworld运行OK.但是, 测试的时候, 很快发现了第一个问题: 在调用LuaJava中提供的LuaState.pushInteger 方法的时候, 出现了错误 : Unsatisfied Link Error . 其他的LuaState.pushNumber 方法倒是没有问题. 用Depends工具看了下, 这个.dll居然没有导出pushInteger 这个函数。(1).下载LuaJava的源代码, 查看了下Luajava.c 和 Luajava.h, 发现果然里面有点问题, 在.h里面定义了JNI中对应Java函数的C函数JNIEXPORT void JNICALL Java_org_keplerproject_luajava_LuaState__1pushInteger 但是.c中没有实现这个函数. 无语, 看来大马虎哪都有啊. 幸亏有源代码, 照猫画虎在Luajava.c中加上这个函数的实现,

(2).然后编译. 编译也出现了问题了, 官方文档中说可以用VC++来Build, 但是没有说官方用的是什么版本. 我用VC2005就不行. 好在Luajava比较小, 就一个.h 一个 .c , 在VC中新建一个.dll项目, 把文件加进去, 修改一下build参数 (Include 需要加上lua的头文件, lib中需要加上lua的.lib文件, 另外要选上 Compile as C Code (/TC) ) Build, 通过了.这时再在Java中调用pushInteger方法就没有问题了.在测试中, 发现Luajava提供的文档中, 对于Lua脚本怎么调用Java对象/方法很详细, 但是在Java中怎么调用Lua函数/取得返回值 就没有. 参考了http://www.lua.org/manual/5.1/manual.html#lua_CFunction 的Lua C文档, 实现了传递对象到Lua中并取得返回值的代码:Test1: 测试传递简单类型, 并取得返回值:Lua 脚本(test.lua):
function test(a,b)return a+bend Java代码:static {//加载Lua5.1.dll, 因为LuaJava最后还是要调用Lua的东西System.loadLibrary("lua5.1");}public static void main(String[] argu) throws LuaException {LuaState L = LuaStateFactory.newLuaState();L.openLibs();//读入Lua脚本int error = L.LdoFile("test.lua");if (error != 0) {System.out.println("Read/Parse lua file error. Exit.");return;}//找到函数testL.getField(LuaState.LUA_GLOBALSINDEX, "test");//参数1压栈L.pushInteger(1);//参数2压栈L.pushInteger(2);//调用!! 一共两个参数, 1个返回值L.call(2, 1);//保存返回值, 到a中L.setField(LuaState.LUA_GLOBALSINDEX, "a");//读入aLuaObject l = L.getLuaObject("a");//打印结果.System.out.println("Result is " + l.getString());L.close();}测试2: 传递Java对象class Value {public int i;public void inc() {i++;}public int get() {return i;}public String toString() {return "Value is " + i;}}Lua脚本: (该脚本中调用两次对象的inc方法, 并调用get方法输出结果)function test1(v)v:inc();v:inc();print("In lua: " .. v:get());return vend Java 代码: (前面都一样, 略)//找到函数est1L.getField(LuaState.LUA_GLOBALSINDEX, "test1");//生成新的对象供测试Value v = new Value();//对象压栈L.pushObjectValue(v);//调用函数test1, 此时1个参数, 1个返回值L.call(1, 1);//结果放在b中.L.setField(LuaState.LUA_GLOBALSINDEX, "b");LuaObject l = L.getLuaObject("b");System.out.println("Result is " + l.getObject());
总结:运行结果:Result is Value is 2In lua: 2 和预期的一致.

如何在Java中使用Lua脚本语言

8. 为什么将lua作为游戏脚本