AngelScript框架介绍

DinS          Written on 2018/1/14

文本介绍angelscript的框架,以增进对库的使用理解。读者应该已经将环境搭建好了。遵循传统,制作一个HelloWorld程序帮助读者理解。

一、AS的SDK

理论上讲,只使用angelscript.h就可以正常使用AS,但是这个方法有些原始,AS作者提供了一些附加代码方便我们使用。

进入下载包,找到add-on。

我们使用选中的这三个附加项来简化使用,把这三个文件夹拷贝到工程的库文件夹下。

里面就是.h和.cpp,同理在项目属性里设置好附加包含目录。不过这里我们需要把这些代码导入到工程里,因为有cpp所以需要编译。

使用添加现有项,当然你也可以建立一个筛选器然后统一放进去。

最后在工程属性里把运行库设置成MT/MTD。

这是因为我们编译lib时用的设置是MT,因此这里也需要相同设置。如果编译时设置的是MD,同理。

区别在哪里?简单的说:
/MD,表示运行时库由操作系统提供一个DLL,程序里不集成。
/MT,表示运行时库由程序集成,程序不再需要操作系统提供运行时库DLL。
于是MD占用空间小,MT可移植性更高。

二、Hello World

都设置完成后就可以开始写代码了:

大图点这里

总体上看起来还是比较流畅、清晰的。目前我们只需要从语义上理解调用过程,具体细节后面再说。一次成功的脚本调用需要4个大阶段。

第一个阶段是准备脚本引擎并注册你希望在脚本里使用到的东西。
注意那个注册字符串,因为c++并没有一个完美的字符串类,比如各种编码格式,因此AS提供了一个机会让调用者自己注册字符串。不过一般而言使用标准库的字符串是首选,为了方便这个过程我们用到了scriptstdstring.h中的RegisterStdString函数,其功能是告诉脚本使用到的字符串都视为string。
注册函数的写法看起来有点可怕,现在就注意那个字符串就好了,这个表明print函数加载到脚本引擎里了,可以供脚本直接调用。

第二个阶段是加载脚本并编译。
在这个阶段我们使用了scriptbuilder.h中提供的类来简化代码。这里出现了模块Module的概念。可以将其理解为一块独立的内存空间,有自己的范围、函数、类等等。一个模块中可以有好几个脚本,一个引擎可以有好几个模块。
我们建立个一个Module,并将脚本加载编译。一个脚本就是一个section,估计使用文件路径来标识唯一section。

第三个阶段是确认对象并执行脚本。
获取之前的模块,然后从其中的脚本中找到要执行的函数。这里void Hello()显然是脚本中出现的一个函数。然后有一个context的概念,这个不需要深入理解,也没涉及什么参数,调用就好了。都准备好后,就执行脚本内容。

第四个阶段是清理,不多说了。

整个过程就是AS的基本框架,后面的扩展也都是基于这个框架而来的。

现在让我们看看脚本:

非常简单,就一个Hello函数,执行了一个print函数。运行看结果:

成功了!
虽然并没有那么激动人心,但是我们应该理解到这个过程中发生了一些很奇妙的事情。
具体而言,我们的代码经过编译后产生的机器语言被文本文件直接调用了,同时文本文件中的字符串被当作一个函数由程序执行了。这个对于c++而言很不简单,实际上这打开了新的可能世界。

三、AS的异常处理

在深入研究AS的其他性质之前,需要说说异常处理。
因为脚本本质上就是文本文件,并且相当于直接运行,所以难免会发生各种错误。如果一个程序要调用脚本,一定需要做好错误处理的准备。
官网总结了使用AS推荐的方式,戏称为“三个凡是”:
凡是注册后一定要检查返回值;
凡是运行脚本后一定要检查返回值;
凡是建立引擎后一定要注册message callback以获取错误具体原因。

因为AS都使用返回值来告知成功与否,所以检查返回值格外重要。至于那个message callback是什么,结合下面的代码讲解。

点这里看大图

message callback也是一个函数,只不过这个函数用于获取具体的出错原因。
一般而言用这个足矣找到错误,当然这里用的是输出到控制台,当然也可以写到文件,是需求而定。

(点这里看大图)

注册message callback跟其他的函数略有不同,照着写即可。

跟之前的代码相比,主要多了返回值检测。
一般而言如果返回值小于0就是错了,抛出异常。其他的也没有太多要注意的,基本上就是一行代码结束后判断一下。
让我们看看运行出错的情况,首先把脚本文件名改了,程序加载不到。

注意有两行输出。第一行是注册的message callback,返回具体原因,第二行是异常内容。

接下来试试把脚本中的Hello改成别的。

只有异常输出,继续会报错。

看来这个大概是比较严重的错误。

再试试把脚本中的print改成别的。

message callback给出了具体的错误位置和原因。甚好。

如果一切正常,message callback不会输出任何内容。

以上就是AS的异常处理,一定要做不要偷懒,否则后面够你受的。

前期准备工作差不多了,现在让我们真正进入angelscript的实质内容,见《AngelScript基础用法:注册函数》和《AngelScript进阶用法:在脚本中使用代码类》和《AngelScript进阶用法:在代码中使用脚本类》。