[.net] Easy Scripting in .NET

Started by
72 comments, last by ppp_vcf 16 years, 5 months ago
Quote:Original post by backtrace
After some playing with this (very useful) code, I still haven't figured out how to specify arguments for the called function. All my attempts have lead me to NullReferenceExceptions....


The way I do it is to have my classes in the script implement a known interface, or inherit from a known class. Then I create the an object of the script's class using Reflection and cast it to the known interface.
Advertisement
Quote:Original post by Rob Loach
Quote:Original post by intrest86
Just curious, is everyone doing this "compile the script at runtime" approach? Are there any major advantages over just loading already compiled assemblies?
These are two completely different designs. On one hand, you're allowing the non-developer to hack away at the scripts, and on the other hand you're allowing the developer to hack away at the API.

The only real difference is giving the scripters an easy to use compile tool that builds their scripts into assemblies ahead of time, and then loading assemblies instead. And if you go this way, you no longer have locked your scripters into a single language.
Turring Machines are better than C++ any day ^_~
Quote:Original post by Saruman
Quote:Original post by deathtrap
So... exactly what are the uses of this? All i see is that you're compiling source code inside your source code.


ROFLMAO! :)


What the hell!? I dont even remember posting such a stupid post.
I'm embarassed i posted that :(
By the way, anyone have any information on connecting C# and Lua? Apparently EVERY SINGLE WEBSITE (notably luaforge) that might conceivably have such a binding is down.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Tao has Lua bindings. I've never used them, so I don't know how they work though.
Quote:Original post by kanato
Tao has Lua bindings. I've never used them, so I don't know how they work though.
Exactly the same as how the C API works. You could pretty much take any C->Lua application and port it to C# without changing any of the Lua function calls, and it would work exactly the same.
Rob Loach [Website] [Projects] [Contact]
Is it possible to return a value/object from a compiled script using MDXInfo's game scripting library? Or even use a referenced object, that what ever is done to it during the script being run is done to the object in the application in which started the script?
Keep in mind that a script could make an exception class that contains code that shouldn't be allowed to run, and simply throw the exception..
If your app is not properly sandboxed, this exception can travel from your script to your main app, which would automatically load the whole assembly that contains the exception into your app domain and would be completely unsecure..
For a mini-project of sorts that I'm doing, I went ahead and made a small script compiler and script loader based on the code that was presented here. So far, everything's been going great, but now I've run into some trouble. Apparently, my scripts, or my program, is, without my knowledge, trying to load a different DLL from the same path (my windows temp directory) everytime my scripts are invoked. Could someone please take a look at my classes and tell me what's going on?

using System;using System.Collections.Generic;using System.Text;using System.IO;using System.CodeDom.Compiler;namespace TheSimsAITest{	/// <summary>	/// Contains methods for doing everything that is neccessary to load	/// all interactive object available from a base folder.	/// </summary>	class InteractionObjectLoader	{		//All scripts available in the base script folder. 		FileInfo[] Scripts;		ScriptCompiler Compiler;		CompilerResults[] Results;		public InteractionObjectLoader( string BasePath )		{			Compiler = new ScriptCompiler();			Results = new CompilerResults[100];			LoadScriptsFromDir( BasePath );		}		/// <summary>		/// Helper function for extracting a filename from a filename + extension		/// parameter string.		/// </summary>		private string ExtractFilename(string Str)		{			string TmpStr;			string Result = "";			for(int i = 0; i < Str.Length; i++)			{				TmpStr = Str.Substring(i, 1);								if(TmpStr.Equals("."))					return Result;				Result = Result + TmpStr;			}			return "";		}		private void LoadScriptsFromDir( string BasePath )		{			DirectoryInfo DirInfo = new DirectoryInfo( BasePath );			Scripts = DirInfo.GetFiles( "*.cs" );			int Counter = 0;			foreach( FileInfo TempScript in Scripts )			{				Counter++;				Results[Counter] = Compiler.CompileScript( DirInfo.FullName + "\\" + TempScript.Name );				Results[Counter].CompiledAssembly.GetType( ExtractFilename(TempScript.Name) ).GetMethod( "Init" ).Invoke( null, null );			}		}	}}


using System;using System.Collections.Generic;using System.Text;using Microsoft.CSharp;using System.CodeDom;using System.CodeDom.Compiler;using System.Reflection;namespace TheSimsAITest{	/// <summary>	/// Basic compiler for compiling and loading C# 	/// files in external object files.	/// </summary>	class ScriptCompiler	{		CSharpCodeProvider CodeProvider;		ICodeCompiler CodeCompiler;		//This program's assembly.		Assembly ProgramAssembly;		public ScriptCompiler()		{			CodeProvider = new CSharpCodeProvider();			CodeCompiler = CodeProvider.CreateCompiler();			//Get this program's assembly, so we may aquire it's path			//during compilation.			ProgramAssembly = Assembly.GetEntryAssembly();		}		public CompilerResults CompileScript(string ScriptName)		{			CompilerParameters Params = new CompilerParameters();			Params.GenerateExecutable = false;			Params.GenerateInMemory = true;			Params.IncludeDebugInformation = false;			Params.TreatWarningsAsErrors = false;			Params.ReferencedAssemblies.Add( "System.dll" );			//For messagebox debugging etc.			Params.ReferencedAssemblies.Add( "System.Windows.Forms.dll" );			//Enables object scripts to use all classes in this program.			Params.ReferencedAssemblies.Add( ProgramAssembly.Location );			CompilerResults results = CodeCompiler.CompileAssemblyFromFile( Params, ScriptName );			return results;		}	}}


The exception is thrown on this line:

Results[Counter].CompiledAssembly.GetType( ExtractFilename(TempScript.Name) ).GetMethod( "Init" ).Invoke( null, null );

The exception is a FileNotFoundException, and the error looks like this:

"Could not load file or assembly 'file///C:\Users\Afr0\AppData\Local\Temp\73ihye8c.dll', or one of it's dependencies. The system cannot find the file specified."

What's weird is that the name of the dll changes everytime the program is run, but the path stays constant. Any help is greatly appreciated! Thanks!
_______________________Afr0Games
The reason why you're code is erring on that line is that what you have is an assembly that was created in memory. What you will need to do is create an instance of something that is defined in the assembly (like a class), then invoke a method of the class of which you created an instance of.

OK, that reads in a really confusing way. Normally I wouldn't whore my own posts like this, but a few weeks back I collated a whole bunch of stuff I learned about this stuff into one post where I explain things line by line.

http://www.gamedev.net/community/forums/topic.asp?topic_id=418038

I hope that helps.

This topic is closed to new replies.

Advertisement