Dynamic Linking To Lua

The lil files produced are most easily used via dynamic linking, in the code. In this approach, you load the assembly in code rather than reference it directly, then use reflection to find the MainFunction and then execute.

 
String scriptName = Path.GetFileNameWithoutExtension(script); 
Assembly assembly = Assembly.LoadFrom(script);  
Type mainClosure = assembly.GetType(scriptName + ".MainFunction");
ConstructorInfo ctor = mainClosure.GetConstructor( new Type[] { typeof(LuaReference) } ); 
LuaClosure cl = (LuaClosure)ctor.Invoke(new Object[] { L.Globals });
L.Stack[L.Stack.Top++] = cl;
cl.Call(L, -1, 0); 
 

This assumes the script lives in the same directory as the exe and that its called script. It loads the assembly and the calls the LuaClosure called "scriptName".MainFunction. The compiler produces this function representing the Lua chunk (the outer most part of lua code).
I tend to iterate across all the lil functions in the exe directory at load time, bring them all into the global lua state, so can then call any functions that the lua files have defined with into the global scope without any runtime assembly loading.
This is the approach used in the LuaTest example and this is the function that does it

 
/// 
/// this loads all scripts (.lil files) in the path provided
/// 
/// 
private void LoadScripts(string path)
{
      String fullPath = Path.GetFullPath(Path.GetDirectoryName(path));
 
      String[] scripts = Directory.GetFiles(fullPath, "*.lil");
      foreach (String s in scripts)
      {
          String scriptName = Path.GetFileNameWithoutExtension(s);
 
          try
          {
               Assembly assembly = Assembly.LoadFrom(s);
 
               Type mainClosure = assembly.GetType(scriptName + ".MainFunction");
               ConstructorInfo ctor = mainClosure.GetConstructor( new Type[] { typeof(LuaReference) } );
               LuaClosure cl = (LuaClosure)ctor.Invoke(new Object[] { L.Globals });
               L.Stack[L.Stack.Top++] = cl;
               cl.Call(L, -1, 0);
 
          }
          catch (Exception e)
          {
               Console.Write("Error loading or running script {0}\n {1}\n", s, e.Message);
               Console.Write("Stack Trace: {0}\n", e.StackTrace);
#endif
          }
      }
}
 

Posted on Sun, 2007-03-04 17:09 by deano
» login or register to post comments