2017-06-15 74 views
0

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

到目前为止,我所看到的唯一的语法是通过创建的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

但由于SY因为它的参数在AppDomain中创建Scriptengine的ntax在2.7.7中被弃用或不可用,所以会导致相同的错误。

另外,我需要添加一个像“FullFrames”等Ironpython选项的字典,这是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(); 

回答

0

的问题是,你必须首先加载Microsoft.Scripting.Hosting大会进入appdomain,以及它的所有依赖程序集,如MSCorLib.dll。由于IronPython ScriptEngine程序集旨在位于其自己的AppDomain中,因此不再有权访问诸如“System.Collections.Generic.IList”之类的程序集。一旦我这样做,这条线的工作:

engine = Python.CreateEngine(sandbox, options); 

同时,它解决了统一崩溃,含IronPython的内存泄漏。缺点是你将无法直接使用IronPython来操作编辑器,缺少一些奇特的权限/ Hotswapping等。

至少没有崩溃,这是一个神的发送。

+0

我应该补充一点,这不是一个完整的解决方案,因为现在范围将无法在IronPython ScriptEngine中使用,并且在没有MarshalByRef/Serialization设计模式的情况下将变量返回到主域。我仍然没有想到的东西。 – karmakat

+0

不!有用!你甚至可以操作Unity GameObjects。我创建AppDomain时使用了以下内容: 'PermissionSet permSet = new PermissionSet(PermissionState.Unrestricted); AppDomain sandbox = AppDomain.CreateDomain(“sandbox”,AppDomain.CurrentDomain.Evidence,info,permSet);' – karmakat