mercredi 17 janvier 2018

C# dynamic compiling - statically referencing compiler class

I've made a voxel based VR game in Unity, and am trying to move some of my code to external files that I can compile at run-time. This will allow users to modify game files that are externally based, without me needing to give them access to all of my source code.

A guy named exodrifter shared a tutorial on how to do this (see here) which I have been essentially able to drag and drop into my project. The one issue is that I cannot reference the class I am using to compile the code in my dynamic code.

I get a NullReferenceException when trying to compile

 Debug.Log(BlockInstantiator.GetBlockType(100))

Compiling happens from the function Compile within the class BlockInstantiator.

The compiling function:

public Assembly Compile(string source)
    {
        var provider = new CSharpCodeProvider();
        var param = new CompilerParameters();

        // Add ALL of the assembly references
        foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            param.ReferencedAssemblies.Add(assembly.Location);
        }

        // Add specific assembly references
        //param.ReferencedAssemblies.Add("System.dll");
        //param.ReferencedAssemblies.Add("CSharp.dll");
        //param.ReferencedAssemblies.Add("UnityEngines.dll");

        // Generate a dll in memory
        param.GenerateExecutable = false;
        param.GenerateInMemory = true;

        // Compile the source
        var result = provider.CompileAssemblyFromSource(param, source);

        if (result.Errors.Count > 0)
        {
            var msg = new StringBuilder();
            foreach (CompilerError error in result.Errors)
            {
                msg.AppendFormat("Error ({0}): {1}\n",
                    error.ErrorNumber, error.ErrorText);
            }
            throw new Exception(msg.ToString());
        }

        // Return the assembly
        return result.CompiledAssembly;
    }

A bit of googling suggests that I need to include the EntryAssembly in my referenced assemblies, but when I access this using

Assembly.GetEntryAssembly()

I get a null reference - as documented here

Also trying to get the entry assembly through other means as answered here has so far been unsuccessful. Are there any alternative ways for me to get around this problem?

Apologies for the long post, Thanks in advance.





Aucun commentaire:

Enregistrer un commentaire