using System; using System.Text; using System.Reflection; using System.Collections.Generic; namespace UniLua { using ULDebug = UniLua.Tools.ULDebug; internal class LuaFFILib { public const string LIB_NAME = "ffi.cs"; public static int OpenLib( ILuaState lua ) { var define = new NameFuncPair[] { new NameFuncPair( "clear_assembly_list", FFI_ClearAssemblyList ), new NameFuncPair( "add_assembly", FFI_AddAssembly ), new NameFuncPair( "clear_using_list", FFI_ClearUsingList ), new NameFuncPair( "using", FFI_Using ), new NameFuncPair( "parse_signature", FFI_ParseSignature ), new NameFuncPair( "get_type", FFI_GetType ), new NameFuncPair( "get_constructor", FFI_GetConstructor ), new NameFuncPair( "get_static_method", FFI_GetStaticMethod ), new NameFuncPair( "get_method", FFI_GetMethod ), new NameFuncPair( "call_method", FFI_CallMethod ), new NameFuncPair( "get_field", FFI_GetField ), new NameFuncPair( "get_field_value", FFI_GetFieldValue ), new NameFuncPair( "set_field_value", FFI_SetFieldValue ), new NameFuncPair( "get_prop", FFI_GetProp ), new NameFuncPair( "get_static_prop", FFI_GetStaticProp ), new NameFuncPair( "get_prop_value", FFI_GetPropValue ), new NameFuncPair( "set_prop_value", FFI_SetPropValue ), // new NameFuncPair( "call_constructor", FFI_CallConstructor ), }; lua.L_NewLib( define ); return 1; } private static int FFI_ClearAssemblyList( ILuaState lua ) { AssemblyList.Clear(); return 0; } private static int FFI_AddAssembly( ILuaState lua ) { var name = lua.ToString(1); Assembly assembly = assembly = Assembly.Load(name); if( assembly != null ) AssemblyList.Add( assembly ); else ULDebug.LogError("assembly not found:" + name); return 0; } private static int FFI_ClearUsingList( ILuaState lua ) { UsingList.Clear(); return 0; } private static int FFI_Using( ILuaState lua ) { var name = lua.ToString(1); UsingList.Add( name ); return 0; } // return `ReturnType', `FuncName', `ParameterTypes' private static int FFI_ParseSignature( ILuaState lua ) { var signature = lua.ToString(1); var result = FuncSignatureParser.Parse( lua, signature ); if( result.ReturnType != null ) lua.PushString( result.ReturnType ); else lua.PushNil(); lua.PushString( result.FuncName ); if( result.ParameterTypes != null ) { lua.NewTable(); for( int i=0; i AssemblyList; private static List UsingList; static LuaFFILib() { AssemblyList = new List(); UsingList = new List(); } private static Type FindTypeInAllAssemblies(string typename) { Type result = null; for( var i=0; i(); while( Lexer.Token.TokenType == (int)TK.NAME ) { typelist.Add( CheckName() ); if( ! TestNext( (int)',' ) ) break; } Result.ParameterTypes = typelist.ToArray(); } private void FuncArgs() { if( Lexer.Token.TokenType == (int)'(' ) { var line = Lexer.LineNumber; Lexer.Next(); if( TestNext( (int)')' ) ) { Result.ParameterTypes = new string[0]; return; } TypeList(); CheckMatch( (int)')', (int)'(', line ); } } private bool TestNext( int tokenType ) { if( Lexer.Token.TokenType == tokenType ) { Lexer.Next(); return true; } else return false; } private void ErrorExpected( int token ) { Lexer.SyntaxError( string.Format( "{0} expected", ((char)token).ToString() ) ); } private void CheckMatch( int what, int who, int where ) { if( !TestNext( what ) ) { if( where == Lexer.LineNumber ) ErrorExpected( what ); else Lexer.SyntaxError( string.Format( "{0} expected (to close {1} at line {2})", ((char)what).ToString(), ((char)who).ToString(), where ) ); } } } } }