//C# 使用 InvokeMember 调用 aardio import dotNet; var compiler = dotNet.createCompiler("C#"); compiler.Parameters.CompilerOptions = "/optimize"; compiler.Source = /****** using System; using System.Reflection; using System.Collections; namespace CSharpLibrary { public class DynObject : IEnumerable { private object target; private Type type; public DynObject(object aardioObject) { target = aardioObject; type = target.GetType(); } IEnumerator IEnumerable.GetEnumerator() {return (target as IEnumerable).GetEnumerator(); } public object InvokeMember(string method, params object[] args) { return type.InvokeMember(method, BindingFlags.InvokeMethod, null, target, args); } public object InvokeMember(int dispId, params object[] args){ return type.InvokeMember("[DispId=" + dispId + "]", BindingFlags.InvokeMethod, null, target, args); } public object Invoke(params object[] args) {return type.InvokeMember("", BindingFlags.InvokeMethod, null, target, args); } public object this[string index] { get { return type.InvokeMember(index, BindingFlags.GetProperty, null, target, null); } set { type.InvokeMember(index, BindingFlags.SetProperty, null, target, new object[] { value }); } } } public class Object { public object Hello(object aardioObject) { //转换 aardio 对象 DynObject tab = new DynObject(aardioObject); //调用成员函数 tab.InvokeMember("执行aardio", " console.log('在C#中执行aardio代码') "); //调用 对象自身(如果对象不是函数而是表,调用表对象的 _call 元方法) tab.Invoke(12, 3, this); //遍历 aardio 对象 foreach (object item in tab) { Console.WriteLine("C#中遍历aardio对象键名:" + item); } //修改属性 tab["属性名"] = 456; //读取属性 return tab["属性名"]; } } } ******/ compiler.import("CSharpLibrary"); //使用 C# 编写的类构造对象实例 var cSharpObject = CSharpLibrary.Object(); import console; var aardioObject = { 属性名 = 123; 执行aardio = function( code ){ loadcode(code)(); return 123; }; @{ _call = function(a,b,netObject){ /* aardio 函数传给 .NET 时(委托、事件), aardio 会在原函数外包装一层代理函数,并自动处理回调参数。 回调 aardio 函数的参数中的 .NET 对象会自动封装为 dotNet.object 。 但 .NET 反过来直接回调 aardio 对象的成员函数时, 回调 aardio 函数的参数中的 .NET 对象没有经过处理,不会自动封装为 dotNet.object 。 原生 .NET 对象在 aardio 中存为 COM 对象, 而原生 COM 接口不支持 .NET 的很多特性,例如重载(函数名相同,参数不同)。 .NET 原生对象传入 com.IsNetObject() 会返回非 0 值。 而 dotNet.object 传入 dotNet.getObject() 会返回非 null 值。 解决方案: 如下将原生 .NET 对象转换为 aardio 中的 dotNet.object 。 */ netObject = dotNet.object(netObject); //无论.NET 回调是否在同一线程,被 .NET 回调的 aardio 函数总是在原调用线程执行(不必考虑多线程规则与同步)。 console.log("aardio 对象被 C# 调用了,参数:",a,b) return a + b; } } } //调用实时编译的 C# 函数 var ret = cSharpObject.Hello( aardioObject ); console.dump(ret); console.dumpJson(aardioObject); console.pause();