1. 程式人生 > >Vczh Free Script 2.0 最新.NET介面完成!

Vczh Free Script 2.0 最新.NET介面完成!

    依然是上一篇文章的程式,換了C#寫。

    在Vczh Free Script 2.0的接口裡面,我力求讓C++和.NET兩種語言的介面都趨於一致。目前達到了這個目標,C#僅僅比C++多了兩個輔助函式。外掛那一部分是相當難寫啊。Vczh Free Script 2.0的C++介面允許外掛和指令碼交替呼叫。指令碼引擎是原生代碼,做到跟C#『交替呼叫』基本上是不可能的。上次看過一篇文章,在原生代碼中呼叫託管程式碼,用了無窮多pin和com,於是我換了一種辦法:使用Vczh Free Script 2.0提供的介面,用託管C++重新實現了一次外掛。所幸程式碼不長,大概一千行左右吧。

    下面是Vczh Free Script 2.0在C#中的使用方法。這個程式讀入一個檔案然後執行,返回結果或者輸出錯誤資訊以及出錯所在行數週邊的程式碼。
  1
 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using freescript_clr;
  6   7 namespace FreeScript_CSharp
  8 {
  9 class VczhClass : FsClass
 10     {
 11 public VczhClass(FsPlugin Plugin)
 12             : base(Plugin, "interpreter_debug")
 13         {
 14
         }
 15  16 publicoverride FsePluginInvoke CallConstructor(int ClassID, FsObject[] Parameters, ref FsObject ErrorMessage, ref FsObject Result)
 17         {
 18             Console.WriteLine("VczhClass is creating");
 19             AddExternalMember(ClassID, "MethodA"0);
 20             AddExternalMember(ClassID, 
"MethodB"1);
 21             AddExternalMember(ClassID, "MethodC"2);
 22 return FsePluginInvoke.Success;
 23         }
 24  25 publicoverride FsePluginInvoke CallMember(int ClassID, int MemberID, FsObject[] Parameters, ref FsObject ErrorMessage, ref FsObject Result)
 26         {
 27 switch (GetMemberID(MemberID))
 28             {
 29 case0:
 30                     Console.WriteLine("VczhClass::MethodA is invoking.");
 31 break;
 32 case1:
 33                     Console.WriteLine("VczhClass::MethodB is invoking.");
 34 break;
 35 case2:
 36                     Console.WriteLine("VczhClass::MethodC is invoking.");
 37 break;
 38             }
 39 return FsePluginInvoke.Success;
 40         }
 41  42 publicoverridevoid CallDestructor(int ClassID)
 43         {
 44             Console.WriteLine("VczhClass is destroying.");
 45         }
 46     }
 47  48 class VczhConsole : FsPlugin
 49     {
 50 private FsObject FWrite =null;
 51 private FsObject FWriteLine =null;
 52 private FsObject FRead =null;
 53 private FsObject FCollect =null;
 54 private VczhClass FVczhClass =null;
 55  56 public VczhConsole(FsEngine Engine, string CodePath)
 57             : base(Engine, "interpretor")
 58         {
 59             FWrite = Engine.CreateExternalResource();
 60             FWriteLine = Engine.CreateExternalResource();
 61             FRead = Engine.CreateExternalResource();
 62             FCollect = Engine.CreateExternalResource();
 63             FVczhClass =new VczhClass(this);
 64  65             GetEnvironment().SetFixedVariable("write", FWrite);
 66             GetEnvironment().SetFixedVariable("writeln", FWriteLine);
 67             GetEnvironment().SetFixedVariable("read", FRead);
 68             GetEnvironment().SetFixedVariable("collect", FCollect);
 69             GetEnvironment().SetFixedVariable("VczhClass", FVczhClass.GetCtor());
 70             GetEnvironment().SetFixedVariable("apppath", Engine.CreateString(CodePath));
 71             GetEnvironment().SetFixedVariable("vmpath", Engine.CreateString(System.AppDomain.CurrentDomain.BaseDirectory.ToString()));
 72         }
 73  74 publicoverride FsePluginInvoke Invoke(int ID, FsObject[] Parameters, ref FsObject ErrorMessage, ref FsObject Result)
 75         {
 76 if (ID == FWrite.GetExternalID())
 77             {
 78 foreach (FsObject Param in Parameters)
 79                 {
 80                     Console.Write(Param.GetReadableString());
 81                 }
 82 return FsePluginInvoke.Success;
 83             }
 84 elseif (ID == FWriteLine.GetExternalID())
 85             {
 86 foreach (FsObject Param in Parameters)
 87                 {
 88                     Console.Write(Param.GetReadableString());
 89                 }
 90                 Console.WriteLine();
 91 return FsePluginInvoke.Success;
 92             }
 93 elseif (ID == FRead.GetExternalID())
 94             {
 95 foreach (FsObject Param in Parameters)
 96                 {
 97                     Console.Write(Param.GetReadableString());
 98                 }
 99                 Result = GetOwnedEngine().CreateString(Console.ReadLine());
100 return FsePluginInvoke.Success;
101             }
102 elseif (ID == FCollect.GetExternalID())
103             {
104                 GetOwnedEngine().CollectGarbage();
105 return FsePluginInvoke.Success;
106             }
107 else108             {
109 return FsePluginInvoke.GiveUp;
110             }
111         }
112     }
113 114 class Program
115     {
116 staticvoid Main(string[] args)
117         {
118 string AppPath = System.AppDomain.CurrentDomain.BaseDirectory.ToString();
119 string CodePath ="";
120 if (args.Length ==0)
121             {
122                 CodePath = AppPath +"Default.free";
123             }
124 else125             {
126                 CodePath = args[0];
127                 AppPath = System.IO.Path.GetDirectoryName(CodePath);
128             }
129 if (AppPath[AppPath.Length -1!='\\')
130             {
131                 AppPath +="\\";
132             }
133 string Code = (new System.IO.StreamReader(CodePath,Encoding.Default)).ReadToEnd();
134             FsEngine Engine =new FsEngine(false);
135 new VczhConsole(Engine, AppPath);
136 137 string ErrorMessage ="";
138             FsCodePage CodePage = Engine.Compile(Code,ref ErrorMessage);
139 if (CodePage!=null)
140             {
141                 Engine.CreateTask(CodePage);
142                 FsObject Result = Engine.CreateNull();
143 144 switch (Engine.Run(ref Result, ref ErrorMessage, false))
145                 {
146 case FseRuntimeStatus.Exception:
147                         {
148                             Console.WriteLine("異常:[第"+ (Engine.RuntimeErrorLine() +1).ToString() +"行]"+ Engine.RuntimeErrorMessage());
149 string[] Lines = Engine.RuntimeErrorCode().Split(newstring[] { "\r\n" }, StringSplitOptions.None);
150                             Console.WriteLine("==============================");
151 for (int i = Engine.RuntimeErrorLine() -5; i <= Engine.RuntimeErrorLine() +5; i++)
152                             {
153 if (i >=0&& i < Lines.Length)
154                                 {
155 if (i == Engine.RuntimeErrorLine())
156                                     {
157                                         Console.Write("");
158                                     }
159 else160                                     {
161                                         Console.Write("");
162                                     }
163                                     Console.WriteLine(Lines[i]);
164                                 }
165                             }
166                             Console.WriteLine("==============================");
167                         }
168 break;
169 case FseRuntimeStatus.Finish:
170 break;
171 default:
172                         Console.WriteLine("未知錯誤。");
173                         Engine.DestroyTask(Engine.GetTaskCount());
174 break;
175                 }
176             }
177 else178             {
179                 Console.WriteLine(ErrorMessage);
180             }
181             Console.ReadLine();
182         }
183     }
184 } posted on 2008-05-30 11:57 陳梓瀚(vczh) 閱讀(2011) 評論(5)  編輯 收藏 引用 所屬分類: Vczh Free Script