当前位置: 首页 > 工具软件 > AngelScript > 使用案例 >

AngelScript实践

毛声
2023-12-01

一直想找一个跨平台的脚本,发现AngelScript简单易用,把我的实践分享给大家,希望能对关注AS的同学有所帮助。

我是用vc6编译的as2.2,把它编译成了一个静态库。

你看一下我的vc6工程中的注释就能明白as的用法。完整的vc6工程见附件,咦,怎么找不到如何上传附件啊。只好把我所有的代码贴在下面,但是你要自己到as的官网上下载他的源码,自己搭建环境了。这些代码也仅供参考一下了。

 

http://www.angelcode.com/angelscript/

 

// as_1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "angelscript.h"
#include "scriptstdstring/scriptstdstring.h"
#include "scriptbuilder/scriptbuilder.h"

using namespace std;

//回调函数,这个函数将收集as的错误信息,并输出到指定文件
void MessageCallback(const asSMessageInfo *msg, void *param)
{
 const char *type = "ERR ";
 if( msg->type == asMSGTYPE_WARNING )
  type = "WARN";
 else if( msg->type == asMSGTYPE_INFORMATION )
  type = "INFO";
 printf("%s (%d, %d) : %s : %s/n", msg->section, msg->row, msg->col, type, msg->message);
}

//例子,将要被注册的全局函数
void print(const string msg)
{
 printf("%s", msg.c_str());
}
//例子,将要被注册的一个类
class CRef
{
public:
 CRef();
 virtual ~CRef();

 void Addref();
 void Release();
 void print();

 int refCount;
};
//
CRef::CRef()
{
    // Let the constructor initialize the reference counter to 1
    refCount = 1;
}
//
CRef::~CRef()
{
 
}
//这个方法需要实现,用于增加引用计数
void CRef::Addref()
{
    // Increase the reference counter
    refCount++;
}
//这个函数需要注册,用于减少引用计数
void CRef::Release()
{
    // Decrease ref count and delete if it reaches 0
    if( --refCount == 0 )
        delete this;
}
//这个全局函数是生成CRef类的工厂函数
CRef *Ref_Factory()
{
    // The class constructor is initializing the reference counter to 1
    return new CRef();
}
//这个函数是一个方法的例子
void CRef::print()
{
    printf("Hello~~~ world!/n");
}

int main(int argc, char* argv[])
{
 //创建脚本引擎实例
 asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
 if (engine == NULL)
 {
  return 0;
 }

 //设置错误信息的回调函数
 int r = engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL);
 if (r < 0)
 {
  engine->Release();
  return 0;
 }

 // AngelScript 没有自己的字符串类型, 就像C++也没有自己的字符串类型一样。AngelScript 的SDK提供
 // 了一些add on 的字符串类型,你可以选取一种,如下的函数选用std::string
 RegisterStdString(engine);

 //注册一个全局函数
 r = engine->RegisterGlobalFunction("void print(const string msg)", asFUNCTION(print), asCALL_CDECL);
 if (r < 0)
 {
  //注册失败
 }

 //注册一个类,在编写脚本时类的数据类型名称是"ref"
 r = engine->RegisterObjectType("ref", 0, asOBJ_REF);
 if (r < 0)
 {
  //注册失败
 }
 //注册这个类的工厂函数
 r = engine->RegisterObjectBehaviour("ref", asBEHAVE_FACTORY, "ref@ f()", asFUNCTION(Ref_Factory), asCALL_CDECL);
 if (r < 0)
 {
  //注册失败
 }

 //注册这个类的引用计数函数
 r = engine->RegisterObjectBehaviour("ref", asBEHAVE_ADDREF, "void f()", asMETHOD(CRef,Addref), asCALL_THISCALL);
 if (r < 0)
 {
  //注册失败
 }
 r = engine->RegisterObjectBehaviour("ref", asBEHAVE_RELEASE, "void f()", asMETHOD(CRef,Release), asCALL_THISCALL);
 if (r < 0)
 {
  //注册失败
 }
 //注册这个类的一个普通方法,甚至可以把一个全局函数注册成这个类的方法,这里并没有这样做
 r = engine->RegisterObjectMethod("ref", "void print()", asMETHOD(CRef,print), asCALL_THISCALL);
 if (r < 0)
 {
  //注册失败
 }

 //在这里,使用了as的另外一个插件,主要是用于加载一个脚本文件
 CScriptBuilder builder;
 //创建一个新模块
 r = builder.StartNewModule(engine, "MyModule");
 if( r < 0 )
 {
  printf("Unrecoverable error while starting a new module./n");
  return 0;
 }
 //加载as脚本文件
 r = builder.AddSectionFromFile("D://test//as_1//1.as");
 if( r < 0 )
 {
  printf("Please correct the errors in the script and try again./n");
  return 0;
 }
 //编译这个脚本文件,会进行语法检查,应该是把编译后的执行代码放到了内存中
 r = builder.BuildModule();
 if( r < 0 )
 {
  printf("Please correct the errors in the script and try again./n");
  return 0;
 }
 
 //到MyModule中找到入口函数,这里是main()函数
 asIScriptModule *mod = engine->GetModule("MyModule");
 int funcId = mod->GetFunctionIdByDecl("void main()");
 if( funcId < 0 )
 {
  printf("The script must have the function 'void main()'. Please add it and try again./n");
  return 0;
 }
 
 //创建执行环境(上下文),
 asIScriptContext *ctx = engine->CreateContext();
 ctx->Prepare(funcId);//准备
 r = ctx->Execute();//执行
 if( r != asEXECUTION_FINISHED )
 {
  // The execution didn't complete as expected. Determine what happened.
  if( r == asEXECUTION_EXCEPTION )
  {
   // An exception occurred, let the script writer know what happened so it can be corrected.
   printf("An exception '%s' occurred. Please correct the code and try again./n", ctx->GetExceptionString());
  }
 }
  
 //清理
 ctx->Release();
 engine->Release();

 return 0;
}

 类似资料: