Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对于可能包含lambda表达式的表达式,如何在Unity player或内置游戏中使用Roslyn编译器?_C#_Unity3d_Lambda_Roslyn - Fatal编程技术网

C# 对于可能包含lambda表达式的表达式,如何在Unity player或内置游戏中使用Roslyn编译器?

C# 对于可能包含lambda表达式的表达式,如何在Unity player或内置游戏中使用Roslyn编译器?,c#,unity3d,lambda,roslyn,C#,Unity3d,Lambda,Roslyn,目前,我正试图在我的Unity项目中使用Roslyn C#编译器在运行时编译一些表达式,这样我就可以将它们作为委托执行,而不是反复重新计算表达式文本。显然,出于性能原因,我需要这个 在与Unity的笨拙行为作了几个月的斗争之后,我终于实现了大约90%的业务逻辑,安装了Unity的NuGet,包括DynamicXpresso(它工作得很好,但不支持lambda表达式,我需要它)如前所述,尝试其他NuGet软件包,如Microsoft.CodeDom.Providers.DotNetCompiler

目前,我正试图在我的Unity项目中使用Roslyn C#编译器在运行时编译一些表达式,这样我就可以将它们作为委托执行,而不是反复重新计算表达式文本。显然,出于性能原因,我需要这个

在与Unity的笨拙行为作了几个月的斗争之后,我终于实现了大约90%的业务逻辑,安装了Unity的NuGet,包括
DynamicXpresso
(它工作得很好,但不支持lambda表达式,我需要它)如前所述,尝试其他NuGet软件包,如Microsoft.CodeDom.Providers.DotNetCompilerPlatform和Microsoft.CodeAnalysis

问题是:

  • 我从一些简单的通用函数开始,形式是
    f(x,y,z)=x*y+z
    ,但这太不灵活了,很快就被放弃了
  • DynamicExpresso
    可以工作,但不支持lambda表达式。似乎可以重写代码以递归方式处理lambda表达式,但我没有足够的时间了
  • Microsoft.CodeAnalysis
    破坏了解决方案,因为它与其他库有冲突,我很难恢复
  • Microsoft.CodeDom.Providers.DotNetCompilerPlatform
    至少不会破坏解决方案,而且我可以在单独的测试项目中使用它而不会出现任何问题(我以前做过几十次),但是在Unity(编辑器和播放器)中,我得到了一个
    System.Security.SecurityException
    (无法模拟令牌)当我尝试使用
    CSharpCodeProvider.compileasemblyfromsource(CompilerParameters,params string[])编译时
看起来在Unity中有一些Roslyn的支持,但我无法让它工作。我的代码如下:

using UnityEngine;
using CSCodeProvider = Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider;

string code = "public static class CompiledExpressions { public static int f(int x) => 2*x; }";

CompilerResults result = null;
Assembly asm = null;

var types = new List<Type>()
{
    typeof(int),
    typeof(Mathf),
    typeof(GameObjectExtensions) // a helper class with extension functions for unimplemented trivial tasks with GameObjects
};

try
{
    CSCodeProvider csprovider = new CSCodeProvider(new OurCompilerSettings()); // OurCompilerSettings just helps locate csc.exe
    CompilerParameters cparams = new CompilerParameters();
    cparams.GenerateExecutable = false;
    cparams.GenerateInMemory = true;
    cparams.ReferencedAssemblies.Clear();
    cparams.ReferencedAssemblies.AddRange(types.Select(t => t.Assembly.Location).Distinct().ToArray());

    result = csprovider.CompileAssemblyFromSource(cparams, new string[] { code }); // here comes the exception
    if (!result.Errors.HasErrors)
        asm = result.CompiledAssembly;
}
catch (Exception ex)
{
    Debug.LogError(ex);
}

if (asm != null)
    // do stuff
使用UnityEngine;
使用CSCodeProvider=Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider;
string code=“public static class CompiledExpressions{public static int f(int x)=>2*x;}”;
CompilerResults结果=null;
汇编asm=null;
变量类型=新列表()
{
类型(int),
类型(Mathf),
typeof(GameObjectExtensions)//一个助手类,带有扩展函数,用于使用GameObjects执行未实现的琐碎任务
};
尝试
{
CSCodeProvider csprovider=new CSCodeProvider(new OurCompilerSettings());//OurCompilerSettings只帮助定位csc.exe
CompilerParameters cparams=新的CompilerParameters();
cparams.GenerateExecutable=false;
cparams.GenerateInMemory=true;
cparams.ReferencedAssembly.Clear();
cparams.ReferencedAssemblys.AddRange(types.Select(t=>t.Assembly.Location).Distinct().ToArray());
result=csprovider.compileasemblyfromsource(cparams,新字符串[]{code});//出现异常
如果(!result.Errors.HasErrors)
asm=result.CompiledAssembly;
}
捕获(例外情况除外)
{
调试日志错误(ex);
}
如果(asm!=null)
//做事
错误是:

System.Security.SecurityException: Couldn't impersonate token.
  at System.Security.Principal.WindowsImpersonationContext..ctor (System.IntPtr token) [0x0001a] in <437ba245d8404784b9fbab9b439ac908>:0 
  at System.Security.Principal.WindowsIdentity.Impersonate (System.IntPtr userToken) [0x00000] in <437ba245d8404784b9fbab9b439ac908>:0 
  at Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Compiler.RevertImpersonation () [0x00006] in <fefe506461e04012a8bd9f406d3641b2>:0 
  at Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Compiler.FromSourceBatch (System.CodeDom.Compiler.CompilerParameters options, System.String[] sources) [0x000c1] in <fefe506461e04012a8bd9f406d3641b2>:0 
  at Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Compiler.CompileAssemblyFromSourceBatch (System.CodeDom.Compiler.CompilerParameters options, System.String[] sources) [0x0001d] in <fefe506461e04012a8bd9f406d3641b2>:0 
  at System.CodeDom.Compiler.CodeDomProvider.CompileAssemblyFromSource (System.CodeDom.Compiler.CompilerParameters options, System.String[] sources) [0x00006] in <ae22a4e8f83c41d69684ae7f557133d9>:0 
  at MyProject.RoslynHelper.Compile () [0x0017e] in C:\Users\myname\source\repos\MyProject\MyProject\Assets\scripts\RoslynHelper.cs:137 
0x00007FF77A09D52C (Unity) StackWalker::GetCurrentCallstack
0x00007FF77A0A0991 (Unity) StackWalker::ShowCallstack
0x00007FF7787E54D5 (Unity) GetStacktrace
0x00007FF77AD020CE (Unity) DebugStringToFile
0x00007FF77A1051E5 (Unity) DebugLogHandler_CUSTOM_Internal_Log
0x000001D42D6000EB (Mono JIT Code) (wrapper managed-to-native) UnityEngine.DebugLogHandler:Internal_Log (UnityEngine.LogType,UnityEngine.LogOption,string,UnityEngine.Object)
0x000001D4534AFF8B (Mono JIT Code) UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
0x000001D42D5F090E (Mono JIT Code) UnityEngine.Logger:Log (UnityEngine.LogType,object)
0x000001D42D5F055A (Mono JIT Code) UnityEngine.Debug:LogError (object)
0x000001D42D5E8B33 (Mono JIT Code) [RoslynHelper.cs:143] MyProject.RoslynHelper:Compile () 
0x000001D42D5910BB (Mono JIT Code) [Game.cs:107] MyProject.Game:.ctor () 
0x000001D45359FDCB (Mono JIT Code) [Game.cs:51] MyProject.Game:get_Instance () 
0x000001D42D613BDB (Mono JIT Code) [InteractionReceiver.cs:312] MyProject.InteractionReceiver:Update () 
0x000001D45317AC38 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)
0x00007FF82844CBB0 (mono-2.0-bdwgc) [mini-runtime.c:2809] mono_jit_runtime_invoke 
0x00007FF8283D2122 (mono-2.0-bdwgc) [object.c:2921] do_runtime_invoke 
0x00007FF8283DB11F (mono-2.0-bdwgc) [object.c:2968] mono_runtime_invoke 
0x00007FF77A01EFEE (Unity) scripting_method_invoke
0x00007FF77A018D3D (Unity) ScriptingInvocation::Invoke
0x00007FF779FE2965 (Unity) MonoBehaviour::CallMethodIfAvailable
0x00007FF779FE2A76 (Unity) MonoBehaviour::CallUpdateMethod
0x00007FF779690D38 (Unity) BaseBehaviourManager::CommonUpdate<BehaviourManager>
0x00007FF779699EB4 (Unity) BehaviourManager::Update
0x00007FF779AC7FE3 (Unity) `InitPlayerLoopCallbacks'::`2'::UpdateScriptRunBehaviourUpdateRegistrator::Forward
0x00007FF779AB13D8 (Unity) ExecutePlayerLoop
0x00007FF779AB14AD (Unity) ExecutePlayerLoop
0x00007FF779AB66F4 (Unity) PlayerLoop
0x00007FF777EC60FB (Unity) PlayerLoopController::UpdateScene
0x00007FF777EC4038 (Unity) Application::TickTimer
0x00007FF778809740 (Unity) MainMessageLoop
0x00007FF7788134DA (Unity) WinMain
0x00007FF77B79B012 (Unity) __scrt_common_main_seh
0x00007FF864D44034 (KERNEL32) BaseThreadInitThunk
0x00007FF867903691 (ntdll) RtlUserThreadStart
System.Security.SecurityException:无法模拟令牌。
位于:0中的System.Security.Principal.WindowsImpersonationContext..ctor(System.IntPtr令牌)[0x0001a]
位于:0中的System.Security.Principal.WindowsIdentity.Impersonate(System.IntPtr userToken)[0x00000]处
位于:0中的Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Compiler.RevertImpersonation()[0x00006]
位于Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Compiler.FromSourceBatch(System.CodeDom.Compiler.CompilerParameters选项,System.String[]sources)[0x000c1]中:0
位于Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CompileAsemblyFromSourceBatch(System.CodeDom.Compiler.CompilerParameters选项,System.String[]源)[0x0001d]中:0
位于:0中的System.CodeDom.Compiler.CodeDomProvider.CompileAsemblyFromSource(System.CodeDom.Compiler.CompilerParameters选项,System.String[]sources)[0x00006]
在C:\Users\myname\source\repos\MyProject\MyProject\Assets\scripts\roslynheloper.cs:137中的MyProject.roslynheloper.Compile()[0x0017e]中
0x00007FF77A09D52C(Unity)StackWalker::GetCurrentCallstack
0x00007FF77A0A0991(Unity)StackWalker::ShowCallstack
0x00007FF7787E54D5(统一)GetStacktrace
0x00007FF77AD020CE(统一)调试字符串文件
0x00007FF77A1051E5(统一)调试日志处理程序\自定义\内部\日志
0x000001D42D6000EB(Mono JIT代码)(包装器管理为本机)UnityEngine.DebugLogHandler:Internal_日志(UnityEngine.LogType,UnityEngine.LogOption,string,UnityEngine.Object)
0x000001D4534AFF8B(Mono JIT代码)UnityEngine.DebugLogHandler:LogFormat(UnityEngine.LogType,UnityEngine.Object,string,Object[])
0x000001D42D5F090E(Mono JIT代码)UnityEngine.Logger:Log(UnityEngine.LogType,对象)
0x000001D42D5F055A(Mono JIT代码)UnityEngine.Debug:LogError(对象)
0x000001D42D5E8B33(Mono JIT代码)[roslynheloper.cs:143]MyProject.roslynheloper:Compile()
0x000001D42D5910BB(Mono JIT代码)[Game.cs:107]MyProject.Game:.ctor()
0x000001D45359FDCB(MonoJIT代码)[Game.cs:51]MyProject.Game:get\u实例()
0x000001D42D613BDB(Mono JIT代码)[InteractionReceiver.cs:312]MyProject.InteractionReceiver:Update()
0x000001D45317AC38(Mono JIT代码)(包装器运行时调用)对象:运行时调用\无效\此\对象(对象,intptr,intptr,intptr)
0x00007FF82844CBB0(mono-2.0-bdwgc)[mini-runtime.c:2809]mono\u-jit\u-runtime\u调用
0x00007FF8283D2122(mono-2.0-bdwgc)[object.c:2921]执行运行时调用
0x00007FF8283DB11F(mono-2.0-bdwgc)[object.c:2968]mono_runtime_调用
0x00007FF77A01EFEE(统一)脚本编写方法调用
0x00007FF77A018D3D(统一)脚本调用::调用
0x00007FF779FE2965(统一)单一行为::CallMethodiAvailable
0x00007FF779FE2A76(统一)单一行为::CallUpdateMethod
0x00007FF779690D38(统一)基本行为管理器::CommonUpdate
0x00007FF779699EB4(统一)行为管理器::更新
0x00007FF779AC7FE3(Unity)`InitPlayerLoopCallbacks':`2'::UpdateScript