Vczh Free Script 2.0 最新.NET介面完成!
阿新 • • 發佈:2018-12-27
依然是上一篇文章的程式,換了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
在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
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,
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