序:记得在刚开始学编程的时候,知道了一个字符串并不是一定要在程序中固定死的,而是可以用TEdit.Text来连接的,于是有了一个想法,把一整段代码(几个函数)放在Memo中,想在程序运行的时候通过修改Memo中的内容而让程序能灵活使用.可惜后来失败了.大家看到这一定会笑的半死.的确这是一个很幼稚的想法.后来知道用脚本可以实现程序的灵活运行,可惜一直没有时间研究,这几天刚好要用到脚本,所以研究了一下午,顺便写一点心得.
Python,LUA等都不错,我选择了LUA原因是连接库比较小,扩展方便而Python太庞大了.wow就是使用LUA做为引擎.LUA本是C/C++的连接库,网上有pas的dll连接单元.我是用Delphi来集成的.
LUA的语法类似C,在网上可以找到.具体的使用方法可以见 云风大侠的翻译的手册
http://www.codingnow.com/2000/download/lua_manual.html
脚本示例:
nNum = Num()
function Add(number)
number = number + nNum
return number
end
以上是一个简单的LUA脚本,其中有一个变量nNum和一个函数Add.函数Add的功能是将传入的number+nNum然后返回.nNum的值为调用主程序中的Num函数获得.
LUA要集成到程序中,最基本的要知道一下几点.
1.脚本加载执行.
2.主程序调用脚本中函数.
3.脚本调用主程序函数
4.主程序于脚本变量相互获取
我写了一个简单的类代码如下:
TNpc = class
l: p_lua_state;
FileName : string;
public
constructor Create(sName:string);
destructor Destroy;
procedure Initialize();
procedure run();
end;
function lua_Num(l: p_lua_state): integer; cdecl;
begin
lua_pushnumber(l,30); //返回值30压栈
result := 1; //定义返回参数的数量并不是具体值,此时为1 个
end;
constructor TNpc.Create(sName:string);
begin
FileName := sName;
l := lua_open();
lua_baselibopen(l);// LUA 内嵌 BASE 库
end;
destructor TNpc.Destroy;
begin
lua_close(l);
end;
procedure TNpc.Initialize();
begin
lua_register(l, 'Num', lua_Num); //将主程序中的lua_Num函数注册到引擎中,让脚本用Num来调用
luaL_loadfile(l, Pchar(FileName)); //加载脚本
end;
procedure TNpc.run();
begin
lua_resume(L,0); //脚本使用luaL_loadfile加载时要用lua_resume来返回运行.
lua_getglobal(L, 'add'); //掉用脚本中函数的名称
lua_pushnumber(L, 100); //将脚本中add函数使用的参数压栈
lua_pcall(L, 1, 1,0); //调用函数,有一个参数,一个返回值
Form1.Memo1.Lines.Add(lua_tostring(L,1));//返回的参数
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if npc1 <> nil then npc1.Destroy; //防止内存占用
npc1 := TNpc.Create('npc1.lua'); //创建时传入脚本文件名
npc1.Initialize; //初始化
npc1.run; //运行
end;
特别注意的是脚本中调用主程序函数时,返回参数的设置,程序中默认返回result在脚本引擎中会认为是返回参数的数量,并不是具体的值,而值要先压入栈中才可以.
lua_pushnumber(l,30); //返回值30压栈
result := 1;
脚本加载运行时还可以用lua_dofile(l,FileName).上面的代码我用的是luaL_loadfile和lua_resume来配合.
因为我想让多个类实例来执行不同的脚本.而lua_dofile加载后会直接运行,而luaL_loadfile只是读取脚本到内存并不直接运行.要是运行的时候用lua_resume就可以了.
脚本运行时,是运行非函数外所以代码.函数只有在主程序或脚本函数外掉用的时候才会执行.
LUA 中变量都为全局变量,使用的时候不需要定义.而且要学习LUA的时候要了解汇编,因为函数的返回等都是在栈中保存的.