C# AppDomain语法中的Ironpython脚本引擎

C# AppDomain语法中的Ironpython脚本引擎,c#,unity3d,ironpython,C#,Unity3d,Ironpython,我找不到将Ironpython脚本引擎放入C#中自己的AppDomain的最新语法 到目前为止,我看到的唯一语法是创建脚本引擎,如下所示: AppDomain sandbox = AppDomain.CreateDomain("sandbox"); ScriptEngine engine = Python.CreateEngine( sandbox ); 这不起作用,至少在IPY 2.7.7中不起作用,导致以下异常: SerializationException: Could not find

我找不到将Ironpython脚本引擎放入C#中自己的AppDomain的最新语法

到目前为止,我看到的唯一语法是创建脚本引擎,如下所示:

AppDomain sandbox = AppDomain.CreateDomain("sandbox");
ScriptEngine engine = Python.CreateEngine( sandbox );
这不起作用,至少在IPY 2.7.7中不起作用,导致以下异常:

SerializationException: Could not find type 'System.Collections.Generic.IList`1[[Microsoft.Scripting.Hosting.LanguageSetup, Microsoft.Scripting, Version=1.1.2.22, Culture=neutral, PublicKeyToken=7f709c5b713576e1]]'.
(wrapper xdomain-invoke) System.AppDomain:CreateInstanceAndUnwrap (string,string,bool,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo,object[],System.Security.Policy.Evidence)
(wrapper remoting-invoke-with-check) System.AppDomain:CreateInstanceAndUnwrap (string,string,bool,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo,object[],System.Security.Policy.Evidence)
Microsoft.Scripting.Hosting.ScriptRuntime.CreateRemote (System.AppDomain domain, Microsoft.Scripting.Hosting.ScriptRuntimeSetup setup)
IronPython.Hosting.Python.CreateRuntime (System.AppDomain domain)
IronPython.Hosting.Python.CreateEngine (System.AppDomain domain) 
我还试图给出我所理解的完整参数集,如下所示:

但是,由于使用AppDomain作为其参数创建Scriptengine的语法在2.7.7中已被弃用或不可用,因此会导致相同的错误

此外,我还需要添加一个Ironpython选项字典,如“FullFrames”等,这正是Python.CreateEngine所期望的

我需要将Ironpython放在它自己的AppDomain中,因为在几个程序集加载或引擎的多个实例化之后,似乎存在某种内存泄漏,导致Unity崩溃(我会清空并关闭运行时,并在主例程在IPY中完成时进行垃圾收集)

以下是我目前的工作内容:

Dictionary<string, object> options = new Dictionary<string, object>();
options["Frames"] = true;
options["FullFrames"] = true;
options["LightweightScopes"] = true;
options["ShowClrExceptions"] = true;
options["ExceptionDetail"] = true;

AppDomain sandbox = AppDomain.CreateDomain("sandbox");
// Don't know where to go from here to get my engine into the AppDomain.

engine = Python.CreateEngine(options);
scope = engine.CreateScope();

var paths = engine.GetSearchPaths();
paths.Add(@"C:\Python\IronPython2.7.7\Lib");
paths.Add(@"C:\Python\IronPython2.7.7\Lib\site-packages");
engine.SetSearchPaths(paths);

scope.SetVariable("test", "12345");

try
{
    source.Execute(scope);
}
catch (SystemExitException e)
{
    Debug.Log("IronPython exited with the following code ( " + e + " )");
}
catch (Exception e)
{
    ExceptionOperations eo = engine.GetService<ExceptionOperations>();
    string error = eo.FormatException(e);
    Debug.Log("<color=red>IPYError : </color>" + error);
}

engine.Runtime.Shutdown();
engine = null;
runtime = null;
source = null;
scope = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
字典选项=新建字典();
选项[“帧”]=true;
选项[“完整帧”]=true;
选项[“LightweightScopes”]=true;
选项[“ShowClrExceptions”]=true;
选项[“ExceptionDetail”]=true;
AppDomain沙盒=AppDomain.CreateDomain(“沙盒”);
//不知道从这里到哪里才能让我的引擎进入AppDomain。
engine=Python.CreateEngine(选项);
scope=engine.CreateScope();
var path=engine.getSearchPath();
Add(@“C:\Python\IronPython2.7.7\Lib”);
添加(@“C:\Python\IronPython2.7.7\Lib\site packages”);
引擎。设置搜索路径(路径);
范围。设置变量(“测试”、“12345”);
尝试
{
来源、执行(范围);
}
捕获(SystemExitexE)
{
Log(“IronPython退出时带有以下代码(“+e+”));
}
捕获(例外e)
{
ExceptionOperations eo=engine.GetService();
字符串错误=eo.FormatException(e);
Log(“IPYError:+错误”);
}
engine.Runtime.Shutdown();
引擎=空;
运行时=null;
source=null;
scope=null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

问题是,您必须首先将Microsoft.Scripting.Hosting程序集及其所有依赖程序集(如MSCorLib.dll)加载到appdomain中。由于IronPython脚本引擎程序集应该位于它自己的AppDomain中,因此它不再具有对诸如“System.Collections.Generic.IList”等程序集的访问权限。一旦我这么做了,这句话就奏效了:

engine = Python.CreateEngine( sandbox, options);
此外,它还修复了Unity崩溃,其中包含IronPython内存泄漏。缺点是,您将无法使用IronPython直接操作编辑器,缺少一些奇特的权限/热交换等


至少不再发生崩溃,这是天赐良机。

我应该补充一点,这不是一个完整的解决方案,因为现在scope无法在IronPython脚本引擎中工作,也无法在没有MarshallByRef/序列化设计模式的情况下将VAR返回主域。有些事我还没弄明白。没有!它起作用了!你甚至可以操纵Unity游戏对象。我在创建AppDomain时使用了以下命令:
PermissionSet permSet=newpermissionset(PermissionState.Unrestricted);AppDomain沙盒=AppDomain.CreateDomain(“沙盒”,AppDomain.CurrentDomain.Evidence,info,permSet)