聚星亭

吾笨笨且懒散兮 急须改之而奋进
posts - 74, comments - 166, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

       AngelScript作为一个嵌入式的脚本库不支持独立运作(原文: Being an embedded scripting library there isn't much that AngelScript allows the scripts to do by themselves,)       因此,应用程序必须先注册一个接口让脚本与应用程序交互(原文:so the first thing the application must do is to register the interface that the script will have to interact with the application.)。该接口可以由函数、变量、甚至是一个完整的类组成(原文:The interface may consist of functions, variables, and even complete classes.)。

// 创建一个脚本引擎

asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

 

// 设置一个消息回调来接收可读的错误信息

// 建议在创建一个引擎对象后这样做一下, 因为如果注册失败,本引擎可以发送一些有效信息到消息流中

r = engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL); assert( r >= 0 );

 

//由于标准的C++中没有明确的字符串类型,因此,AngelScript也没有内置的字符串类型.

//故每个开发人员可以自由注册它自己的字符串类型

//但是本引擎SDK为注册一个字符串类型提供了一个标准的附加项,因此如果你不想注册,就没有必要进行注册  

RegisterStdString(engine);

 

// 注册一个脚本中的函数

r = engine->RegisterGlobalFunction("void print(const string &in)", \

                                asFUNCTION(print), asCALL_CDECL); assert( r >= 0 );

 

       配置好引擎之后,下一步便是编译要执行的脚本了(原文:After the engine has been configured, the next step is to compile the scripts that should be executed.)。接下来是一个注册print函数将“Hello world”写在标准输出流中。例如,下面test.as文件中存储的代码(原文: The following is our script that will call the registered print function to write Hello world on the standard output stream. Let's say it's stored in the file test.as.:

void main()

{

  print("Hello world\n");

}

 

       下面的代码是加载脚本文件并编译(Here's the code for loading the script file and compiling it. ):

// CScriptBuilder类是一个装在文件的附加物

//如果有必要的话,通过执行一个预处理, 然后告诉引擎组建一个脚本模块

CScriptBuilder builder;

r = builder.BuildScriptFromFile(engine, "MyModule", "test.as");

if( r < 0 )

{

  // 产生一个错误. 把它列在标准输出流中以通知脚本作者修正脚本错误

  printf("Please correct the errors in the script and try again.\n");

  return;

}

       最后一步是关联要被调用的函数,并建立上下文来执行它(原文:The last step is to identify the function that is to be called, and set up a context for executing it. )

 

// 定位到被调用的函数

asIScriptModule *mod = engine->GetModule("MyModule");

int funcId = mod->GetFunctionIdByDecl("void main()");

if( funcId < 0 )

{

  // 找不到这个函数(The function couldn't be found.)

  // 通知脚本作者在脚本中包含指定的函数.

  printf("The script must have the function 'void main()'. Please add it and try again.\n");

  return;

}

 

// 创建一个引擎环境, 配置一下, 然后执行

asIScriptContext *ctx = engine->CreateContext();

ctx->Prepare(funcId);

r = ctx->Execute()

if( r != asEXECUTION_FINISHED )

{

  // The execution didn't complete as expected. 确定发生了什么.

  if( r == asEXECUTION_EXCEPTION )

  {

    // 发生一个异常, 让脚本作者知道发生了什么,怎样才可以修正它.

    printf("An exception '%s' occurred. Please correct the code and try again.\n", ctx->GetExceptionString());

  }

}

 

       上面试最基本的异常处理(原文:The exception handling above is very basic.)。如果需要,该应用程序也可以获得关于行号、函数、调用堆栈信息、以及本地和全局变量(原文:The application may also obtain information about line number, function, call stack, and even values of local and global variables if wanted. )。

       在虚拟机执行完之后,不要忘了清理一下(原文:Don't forget to clean up after you're done with the engine.

// 清理

ctx->Release();

engine->Release();

 

       Helper functions

       print 函数是对printf函数很简单封装(The print function is implemented as a very simple wrapper on the printf function.)。

// 打印脚本字符串到标准输出流

void print(string &msg)

{

  printf("%s", msg.c_str());

}

另见:

       Message callback, Script builder helper, and string object (STL)

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理