AppDomain 语法中的 Ironpython ScriptEngine

Ironpython ScriptEngine in AppDomain syntax

我找不到在 C# 中将 Ironpython ScriptEngine 放入它自己的 AppDomain 的最新语法。

到目前为止我看到的唯一语法是像这样创建 ScriptEngine:

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) 

我也尝试按照我的理解给出完整的参数集,如下所示: http://answers.unity3d.com/questions/242901/problem-with-appdomainspermissionset-ironpython-in.html

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

此外,我确实需要添加 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();

问题是您必须首先将 Microsoft.Scripting.Hosting 的程序集及其所有依赖程序集(例如 MSCorLib.dll)加载到应用程序域中。由于 IronPython ScriptEngine 程序集应该位于它自己的 AppDomain 中,因此它不再有权访问 'System.Collections.Generic.IList' 等程序集。一旦我这样做了,这条线就起作用了:

engine = Python.CreateEngine( sandbox, options);

此外,它还修复了 Unity 崩溃,包含 IronPython 内存泄漏。缺点是您将无法使用 IronPython 直接操作编辑器,缺少一些花哨 permissions/Hotswapping 等

至少没有崩溃了,真是天赐之物。