上一篇研究了如何做到CS和JS互相透明访问的设想,经过一些实践,这里做出了一个小DEMO。
这里有第一个演示类:
public class TestCSClass { public TestCSClass() { } //如果可被重写则重载 public virtual object Method1() { Console.WriteLine("CS CALL!!"); return "Hello CS"; } }
简单的C#代码,然后有个可重载的方法 Metod1
[SharpKit.JavaScript.JsType(SharpKit.JavaScript.JsMode.Clr, PreCode = @" try{ if (typeof (global.JsTypes) != 'undefined') { JsTypes = global.JsTypes; } } catch (e) { } " )] public class TestJSClass : TestCSClass { public string Arg1 { get; set; } public void FunA(string arg) { } public TestJSClass() { } }
这是将要生成JS的类,继承与TestCSClass,有个独有的属性,并且多了一个字段,并且重载了一个方法。
然后是代理JS类,用于绑定C#对象并且拥有一些继承类的基础信息
//C# 代理类 namespace Proxy { //JS代理类 [SharpKit.JavaScript.JsType(TargetType = typeof (CsLibForJS.TestCSClass))] public class TestCSClass { public string __BaseTypeName = "CsLibForJS.TestCSClass"; private object _ExtObject = null; public TestCSClass() { _ExtObject = ClrHelper.CallCtor(this); } public virtual object Method1() { return ClrHelper.CallClr(_ExtObject, "Method1"); } } }
当然这个也是C#的,不然你编译不过去。。
CallClr 就是个反射调用(性能啥的以后再说。。)
我们看看2个类生成的JS代码:
/* Generated by SharpKit 5 v5.4.4 */ try{ if (typeof (global.JsTypes) != 'undefined') { JsTypes = global.JsTypes; } } catch (e) { } if (typeof(JsTypes) == "undefined") var JsTypes = []; var CsLibForJS$TestJSClass = { fullname: "CsLibForJS.TestJSClass", baseTypeName: "CsLibForJS.TestCSClass", assemblyName: "CsLibForJS", Kind: "Class", definition: { ctor: function (){ this._Arg1 = null; CsLibForJS.TestCSClass.ctor.call(this); }, Arg1$$: "System.String", get_Arg1: function (){ return this._Arg1; }, set_Arg1: function (value){ this._Arg1 = value; }, FunA: function (arg){ } } }; JsTypes.push(CsLibForJS$TestJSClass); var CsLibForJS$Proxy$TestCSClass = { fullname: "CsLibForJS.Proxy.TestCSClass", baseTypeName: "System.Object", assemblyName: "CsLibForJS", Kind: "Class", definition: { ctor: function (){ this.__BaseTypeName = "CsLibForJS.TestCSClass"; this._ExtObject = null; System.Object.ctor.call(this); this._ExtObject = CsLibForJS.ClrHelper.CallCtor(this); }, Method1: function (){ return CsLibForJS.ClrHelper.CallClr(this._ExtObject, "Method1"); } } }; JsTypes.push(CsLibForJS$Proxy$TestCSClass);
为了避免混淆,所以代理类的名字空间带,Proxy,在处理类关系的时候会在jsclr中替换掉。
然后我们开始第一个调用。。
首先从JS开始:
var csobj = new CsLibForJS.TestCSClass.ctor(); var jsobj =new CsLibForJS.TestJSClass.ctor(); log("JSCALL"); log(csobj.Method1()); log(jsobj.Method1());
new出一个基础类, new出一个继承类,一个代理类,
而jsobj中是没有 Method1的,执行,输出为:(>>开头为JS输出)
>>JSCALL CS CALL!! >>Hello CS CS CALL!! >>Hello CS
绑定了基础对象后,我们JS类可以直接有个属性指向C#的基础类,所以在调用当前方法的时候可以直接通过反射调用对象类中的方法。
然后我们在把JS类中改成重载方法1:
public class TestJSClass : TestCSClass { public string Arg1 { get; set; } public void FunA(string arg) { } public TestJSClass() { } public override object Method1() { return "Hello JS"; } }
再执行:
>>JSCALL CS CALL!! >>Hello CS >>Hello JS
我们已经从JS中覆盖了原有的Method1方法,(废话么- -。。。)
咱继续。。。从CS中调用CS方法,并且重载
新建个JS代理类:
namespace JSProxy { public class TestCSClass : CsLibForJS.TestCSClass { public Jint.Native.Object.ObjectInstance __bindJsObject; public TestCSClass() { } //重载的方法 public override object Method1() { //被重写 if (__bindJsObject.HasProperty("Method1")) { return __bindJsObject.Get("Method1").As<Jint.Native.Function.FunctionInstance>().Call(__bindJsObject,new JsValue[0]); } else { return base.Method1(); } } } }
调用过程:
TestCSClass localclass = new JSProxy.TestCSClass() { __bindJsObject = engine.Execute("new CsLibForJS.TestJSClass.ctor()") .GetCompletionValue() .As<Jint.Native.Object.ObjectInstance>() }; Console.WriteLine("CSCALL:" + localclass.Method1());
执行:
CSCALL:Hello JS
看起来像重载了么,我们直接手改JS
删掉这句:
public override object Method1() { return "Hello JS"; }
执行:
CSCALL:Hello CS
附送个性能测试:
var sw = new Stopwatch(); sw.Start(); for (int i = 0; i < 10000*10; i++) { localclass = new JSProxy.TestCSClass() { __bindJsObject = ctor.Construct(new JsValue[0]) }; localclass.Method1(); } sw.Stop(); Console.WriteLine("loopTime:" + sw.ElapsedMilliseconds);
loopTime:6219
谢谢观赏~
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-08 22:38:58