Example #1
0
        /// <summary>
        /// 解析Lua脚本
        /// </summary>
        /// <returns>返回值</returns>
        /// <param name="script">Lua脚本</param>
        public LuaValue evalScript(string script)
        {
            IntPtr resultPtr = IntPtr.Zero;
            int    size      = NativeUtils.evalScript(_nativeObjectId, script, out resultPtr);

            return(LuaObjectDecoder.DecodeObject(resultPtr, size) as LuaValue);
        }
Example #2
0
        /// <summary>
        /// 初始化上下文
        /// </summary>
        public LuaContext()
        {
            _regTypes           = new HashSet <Type> ();
            _methodHandlers     = new Dictionary <string, LuaMethodHandler> ();
            _exportsTypeManager = new LuaExportsTypeManager(this);
            _nativeObjectId     = NativeUtils.createLuaContext();
            _contexts.Add(_nativeObjectId, new WeakReference(this));

            //初始化异常消息捕获
            IntPtr fp = Marshal.GetFunctionPointerForDelegate(new LuaExceptionHandleDelegate(luaException));

            NativeUtils.setExceptionHandler(_nativeObjectId, fp);

                        #if UNITY_ANDROID && !UNITY_EDITOR
            AndroidJavaObject luaCacheDir = getLuaCacheDir();
            if (!luaCacheDir.Call <bool> ("exists", new object[0]))
            {
                luaCacheDir.Call <bool> ("mkdirs", new object[0]);
            }

            addSearchPath(luaCacheDir.Call <string> ("toString", new object[0]));
                        #else
            //增加搜索路径
            addSearchPath(Application.streamingAssetsPath);
                        #endif
        }
Example #3
0
        /// <summary>
        /// 从Lua脚本文件中解析Lua脚本
        /// </summary>
        /// <returns>返回值</returns>
        /// <param name="filePath">Lua脚本文件路径</param>
        public LuaValue evalScriptFromFile(string filePath)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            if (!filePath.StartsWith("/") || filePath.StartsWith(Application.streamingAssetsPath, true, null))
            {
                if (filePath.StartsWith(Application.streamingAssetsPath, true, null))
                {
                    filePath = filePath.Substring(Application.streamingAssetsPath.Length + 1);
                }

                //初始化lua的缓存目录
                setupLuaCacheDir();

                filePath = getLuaCacheFilePath(filePath);
            }
#elif UNITY_EDITOR_WIN
            Regex regex = new Regex("^[a-zA-Z]:/.*");
            if (!regex.IsMatch(filePath))
            {
                //Window下不带盘符的路径为相对路径,需要拼接streamingAssetsPath
                filePath = string.Format("{0}/{1}", Application.streamingAssetsPath, filePath);
            }
#else
            if (!filePath.StartsWith("/"))
            {
                filePath = string.Format("{0}/{1}", Application.streamingAssetsPath, filePath);
            }
#endif
            IntPtr   resultPtr;
            int      size     = NativeUtils.evalScriptFromFile(_nativeObjectId, filePath, out resultPtr);
            LuaValue retValue = LuaObjectDecoder.DecodeObject(resultPtr, size) as LuaValue;

            return(retValue);
        }
Example #4
0
        /// <summary>
        /// 调用Lua方法
        /// </summary>
        /// <returns>返回值</returns>
        /// <param name="methodName">方法名</param>
        /// <param name="arguments">调用参数列表</param>
        public LuaValue callMethod(string methodName, List <LuaValue> arguments)
        {
            IntPtr argsPtr   = IntPtr.Zero;
            IntPtr resultPtr = IntPtr.Zero;

            if (arguments != null)
            {
                LuaObjectEncoder encoder = new LuaObjectEncoder();
                encoder.writeInt32(arguments.Count);
                foreach (LuaValue value in arguments)
                {
                    encoder.writeObject(value);
                }

                byte[] bytes = encoder.bytes;
                argsPtr = Marshal.AllocHGlobal(bytes.Length);
                Marshal.Copy(bytes, 0, argsPtr, bytes.Length);
            }

            int size = NativeUtils.callMethod(_nativeObjectId, methodName, argsPtr, out resultPtr);

            if (argsPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(argsPtr);
            }

            if (size > 0)
            {
                return(LuaObjectDecoder.DecodeObject(resultPtr, size) as LuaValue);
            }

            return(new LuaValue());
        }
        /// <summary>
        /// 添加Lua的搜索路径,如果在采用require方法时无法导入其他路径脚本,可能是由于脚本文件的所在路径不在lua的搜索路径中。
        /// 可通过此方法进行添加。
        /// </summary>
        /// <param name="path">路径.</param>
        public void addSearchPath(string path)
        {
            if (!path.StartsWith("/") || path.StartsWith(Application.streamingAssetsPath))
            {
                                #if UNITY_ANDROID && !UNITY_EDITOR
                AndroidJavaObject luaCacheDir = getLuaCacheDir();
                if (!luaCacheDir.Call <bool> ("exists", new object[0]))
                {
                    luaCacheDir.Call <bool> ("mkdirs", new object[0]);
                }
                string cachePath = luaCacheDir.Call <string> ("toString", new object[0]);

                if (path.StartsWith(Application.streamingAssetsPath))
                {
                    path = path.Substring(Application.streamingAssetsPath.Length + 1);
                }

                path = string.Format("{0}/{1}", cachePath, path);
                                #else
                if (!path.StartsWith("/"))
                {
                    path = string.Format("{0}/{1}", Application.streamingAssetsPath, path);
                }
                                #endif
            }


            NativeUtils.addSearchPath(_nativeObjectId, path + "/?.lua");
        }
Example #6
0
        /// <summary>
        /// 设置对象
        /// </summary>
        /// <param name="keyPath">键名路径.</param>
        /// <param name="value">值.</param>
        public void setObject(String keyPath, object value)
        {
            if (_context != null && _tableId > 0 && type == LuaValueType.Map)
            {
                LuaValue objectValue = new LuaValue(value);

                IntPtr resultPtr = IntPtr.Zero;

                IntPtr           valuePtr = IntPtr.Zero;
                LuaObjectEncoder encoder  = new LuaObjectEncoder(_context);
                encoder.writeObject(objectValue);

                byte[] bytes = encoder.bytes;
                valuePtr = Marshal.AllocHGlobal(bytes.Length);
                Marshal.Copy(bytes, 0, valuePtr, bytes.Length);

                int bufferLen = NativeUtils.tableSetObject(_tableId, keyPath, valuePtr, resultPtr);

                if (bufferLen > 0)
                {
                    LuaValue resultValue = LuaObjectDecoder.DecodeObject(resultPtr, bufferLen, _context) as LuaValue;
                    _value = resultValue._value;
                }

                if (valuePtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(valuePtr);
                }
            }
        }
Example #7
0
        /// <summary>
        /// 调用方法
        /// </summary>
        /// <param name="arguments">参数列表</param>
        /// <param name="scriptController">脚本控制器</param>
        public LuaValue invoke(List <LuaValue> arguments, LuaScriptController scriptController)
        {
            int scriptControllerId = 0;

            if (scriptController != null)
            {
                scriptControllerId = scriptController.objectId;
            }

            IntPtr funcPtr   = IntPtr.Zero;
            IntPtr argsPtr   = IntPtr.Zero;
            IntPtr resultPtr = IntPtr.Zero;

            LuaObjectEncoder funcEncoder = new LuaObjectEncoder(_context);

            funcEncoder.writeObject(this);

            byte[] bytes = funcEncoder.bytes;
            funcPtr = Marshal.AllocHGlobal(bytes.Length);
            Marshal.Copy(bytes, 0, funcPtr, bytes.Length);

            if (arguments != null)
            {
                LuaObjectEncoder argEncoder = new LuaObjectEncoder(_context);
                argEncoder.writeInt32(arguments.Count);
                foreach (LuaValue value in arguments)
                {
                    argEncoder.writeObject(value);
                }

                bytes   = argEncoder.bytes;
                argsPtr = Marshal.AllocHGlobal(bytes.Length);
                Marshal.Copy(bytes, 0, argsPtr, bytes.Length);
            }

            int size = NativeUtils.invokeLuaFunction(_context.objectId, funcPtr, argsPtr, scriptControllerId, out resultPtr);

            if (argsPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(argsPtr);
            }
            if (funcPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(funcPtr);
            }

            if (size > 0)
            {
                return(LuaObjectDecoder.DecodeObject(resultPtr, size, _context) as LuaValue);
            }

            return(new LuaValue());
        }
Example #8
0
        /// <summary>
        /// 获取全局变量
        /// </summary>
        /// <returns>变量值.</returns>
        /// <param name="name">变量名称.</param>
        public LuaValue getGlobal(string name)
        {
            IntPtr valuePtr = IntPtr.Zero;
            int    size     = NativeUtils.getGlobal(_nativeObjectId, name, out valuePtr);

            if (valuePtr != IntPtr.Zero && size > 0)
            {
                LuaObjectDecoder decoder = new LuaObjectDecoder(valuePtr, size, this);
                return(decoder.readObject() as LuaValue);
            }

            return(new LuaValue());
        }
Example #9
0
        /// <summary>
        /// 注册Lua方法
        /// </summary>
        /// <param name="methodName">方法名称</param>
        /// <param name="handler">事件处理器</param>
        public void registerMethod(string methodName, LuaMethodHandler handler)
        {
            _methodHandlers [methodName] = handler;

            if (_methodHandleDelegate == null)
            {
                _methodHandleDelegate = new LuaMethodHandleDelegate(luaMethodRoute);
            }

            IntPtr fp = Marshal.GetFunctionPointerForDelegate(_methodHandleDelegate);

            NativeUtils.registerMethod(_nativeObjectId, methodName, fp);
        }
Example #10
0
        /// <summary>
        /// 注册模块
        /// </summary>
        /// <param name="context">Lua上下文.</param>
        /// <param name="moduleName">模块名称.</param>
        /// <param name="t">类型.</param>
        protected static void _register(LuaContext context, string moduleName, Type t)
        {
            //初始化模块导出信息
            Dictionary <string, MethodInfo> exportMethods = new Dictionary <string, MethodInfo> ();
            List <string> exportMethodNames = new List <string> ();

            MethodInfo[] methods = t.GetMethods();
            foreach (MethodInfo m in methods)
            {
                if (m.IsStatic && m.IsPublic)
                {
                    //静态和公开的方法会导出到Lua
                    exportMethodNames.Add(m.Name);
                    exportMethods.Add(m.Name, m);
                }
            }

            IntPtr exportMethodNamesPtr = IntPtr.Zero;

            if (exportMethodNames.Count > 0)
            {
                LuaObjectEncoder encoder = new LuaObjectEncoder();
                encoder.writeInt32(exportMethodNames.Count);
                foreach (string name in exportMethodNames)
                {
                    encoder.writeString(name);
                }

                byte[] bytes = encoder.bytes;
                exportMethodNamesPtr = Marshal.AllocHGlobal(bytes.Length);
                Marshal.Copy(bytes, 0, exportMethodNamesPtr, bytes.Length);
            }

            if (_moduleMethodHandleDelegate == null)
            {
                _moduleMethodHandleDelegate = new LuaModuleMethodHandleDelegate(luaModuleMethodRoute);
            }
            IntPtr fp = Marshal.GetFunctionPointerForDelegate(_moduleMethodHandleDelegate);

            //注册模块
            int moduleId = NativeUtils.registerModule(context.objectId, moduleName, exportMethodNamesPtr, fp);

            //关联注册模块的注册方法
            _exportsModuleMethods.Add(moduleId, exportMethods);

            if (exportMethodNamesPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(exportMethodNamesPtr);
            }
        }
Example #11
0
        /// <summary>
        /// 解析Lua脚本
        /// </summary>
        /// <returns>返回值.</returns>
        /// <param name="script">脚本内容.</param>
        /// <param name="scriptController">脚本控制器.</param>
        public LuaValue evalScript(string script, LuaScriptController scriptController)
        {
            IntPtr resultPtr = IntPtr.Zero;

            int scriptControllerId = 0;

            if (scriptController != null)
            {
                scriptControllerId = scriptController.objectId;
            }

            int size = NativeUtils.evalScript(_nativeObjectId, script, scriptControllerId, out resultPtr);

            return(LuaObjectDecoder.DecodeObject(resultPtr, size, this) as LuaValue);
        }
Example #12
0
        /// <summary>
        /// 执行线程
        /// </summary>
        /// <param name="handler">线程处理器.</param>
        /// <param name="arguments">参数列表.</param>
        /// <param name="scriptController">脚本控制器.</param>
        public void runThread(LuaFunction handler, List <LuaValue> arguments, LuaScriptController scriptController)
        {
            int scriptControllerId = 0;

            if (scriptController != null)
            {
                scriptControllerId = scriptController.objectId;
            }

            IntPtr funcPtr = IntPtr.Zero;
            IntPtr argsPtr = IntPtr.Zero;

            LuaObjectEncoder funcEncoder = new LuaObjectEncoder(this);

            funcEncoder.writeObject(handler);

            byte[] bytes = funcEncoder.bytes;
            funcPtr = Marshal.AllocHGlobal(bytes.Length);
            Marshal.Copy(bytes, 0, funcPtr, bytes.Length);

            if (arguments != null)
            {
                LuaObjectEncoder argEncoder = new LuaObjectEncoder(this);
                argEncoder.writeInt32(arguments.Count);
                foreach (LuaValue value in arguments)
                {
                    argEncoder.writeObject(value);
                }

                bytes   = argEncoder.bytes;
                argsPtr = Marshal.AllocHGlobal(bytes.Length);
                Marshal.Copy(bytes, 0, argsPtr, bytes.Length);
            }

            NativeUtils.runThread(this.objectId, funcPtr, argsPtr, scriptControllerId);

            if (argsPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(argsPtr);
            }
            if (funcPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(funcPtr);
            }
        }
Example #13
0
        /// <summary>
        /// 创建LuaContext
        /// </summary>
        public LuaContext()
        {
            _methodHandlers = new Dictionary <string, LuaMethodHandler> ();
            _nativeObjectId = NativeUtils.createLuaContext();
            _contexts.Add(_nativeObjectId, new WeakReference(this));

                        #if UNITY_ANDROID && !UNITY_EDITOR
            AndroidJavaObject luaCacheDir = getLuaCacheDir();
            if (!luaCacheDir.Call <bool> ("exists", new object[0]))
            {
                luaCacheDir.Call <bool> ("mkdirs", new object[0]);
            }

            addSearchPath(luaCacheDir.Call <string> ("toString", new object[0]));
                        #else
            //增加搜索路径
            addSearchPath(Application.streamingAssetsPath);
                        #endif
        }
Example #14
0
        /// <summary>
        /// 释放Lua层的变量引用,使其内存管理权交回Lua。
        /// 注:判断value能否被释放取决于value所保存的真实对象,所以只要保证保存对象一致,即使value为不同对象并不影响实际效果。
        /// 即:LuaValue *val1 = new LuaValue(obj1);与LuaValue *val2 = new LuaValue(obj1);传入方法中效果相同。
        /// </summary>
        /// <param name="value">value 对应Lua层变量的原生对象Value,如果value为非Lua回传对象则调用此方法无任何效果。.</param>
        public void releaseValue(LuaValue value)
        {
            if (value != null)
            {
                IntPtr           valuePtr = IntPtr.Zero;
                LuaObjectEncoder encoder  = new LuaObjectEncoder(this);
                encoder.writeObject(value);

                byte[] bytes = encoder.bytes;
                valuePtr = Marshal.AllocHGlobal(bytes.Length);
                Marshal.Copy(bytes, 0, valuePtr, bytes.Length);

                NativeUtils.releaseValue(_nativeObjectId, valuePtr);

                if (valuePtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(valuePtr);
                }
            }
        }
Example #15
0
        /// <summary>
        /// 初始化
        /// </summary>
        public static void setup()
        {
            if (_setNativeObjectIdDelegate == null)
            {
                _setNativeObjectIdDelegate = new LuaSetNativeObjectIdHandleDelegate(setNativeObjectId);
            }
            NativeUtils.bindSetNativeObjectIdHandler(Marshal.GetFunctionPointerForDelegate(_setNativeObjectIdDelegate));

            if (_getClassByInstanceDelegate == null)
            {
                _getClassByInstanceDelegate = new LuaGetClassNameByInstanceDelegate(getClassByInstance);
            }
            NativeUtils.bindGetClassNameByInstanceHandler(Marshal.GetFunctionPointerForDelegate(_getClassByInstanceDelegate));

            if (_exportsNativeTypeDelegate == null)
            {
                _exportsNativeTypeDelegate = new LuaExportsNativeTypeDelegate(exportsNativeType);
            }
            NativeUtils.bindExportsNativeTypeHandler(Marshal.GetFunctionPointerForDelegate(_exportsNativeTypeDelegate));
        }
Example #16
0
        /// <summary>
        /// 设置全局变量
        /// </summary>
        /// <param name="name">变量名称.</param>
        /// <param name="value">变量值.</param>
        public void setGlobal(string name, LuaValue value)
        {
            IntPtr valuePtr = IntPtr.Zero;

            if (value != null)
            {
                LuaObjectEncoder encoder = new LuaObjectEncoder(this);
                encoder.writeObject(value);

                byte[] bytes = encoder.bytes;
                valuePtr = Marshal.AllocHGlobal(bytes.Length);
                Marshal.Copy(bytes, 0, valuePtr, bytes.Length);
            }

            NativeUtils.setGlobal(_nativeObjectId, name, valuePtr);

            if (valuePtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(valuePtr);
            }
        }
Example #17
0
        /// <summary>
        /// 从Lua脚本文件中解析Lua脚本
        /// </summary>
        /// <returns>返回值</returns>
        /// <param name="filePath">Lua脚本文件路径</param>
        public LuaValue evalScriptFromFile(string filePath)
        {
                        #if UNITY_ANDROID && !UNITY_EDITOR
            if (!filePath.StartsWith("/") || filePath.StartsWith(Application.streamingAssetsPath, true, null))
            {
                if (filePath.StartsWith(Application.streamingAssetsPath, true, null))
                {
                    filePath = filePath.Substring(Application.streamingAssetsPath.Length + 1);
                }

                //初始化lua的缓存目录
                setupLuaCacheDir();

                filePath = getLuaCacheFilePath(filePath);
            }
                        #else
            if (!filePath.StartsWith("/"))
            {
                filePath = string.Format("{0}/{1}", Application.streamingAssetsPath, filePath);
            }
                        #endif

            IntPtr   resultPtr;
            int      size     = NativeUtils.evalScriptFromFile(_nativeObjectId, filePath, out resultPtr);
            LuaValue retValue = LuaObjectDecoder.DecodeObject(resultPtr, size) as LuaValue;

//			#if UNITY_ANDROID && !UNITY_EDITOR
//
//			if (needRemoveFile && File.Exists(filePath))
//			{
//				File.Delete(filePath);
//			}
//
//			#endif

            return(retValue);
        }
Example #18
0
 /// <summary>
 /// 抛出异常
 /// </summary>
 /// <param name="message">异常消息.</param>
 public void raiseException(string message)
 {
     NativeUtils.raiseException(_nativeObjectId, message);
 }
Example #19
0
 /// <summary>
 /// 判断模块是否注册
 /// </summary>
 /// <returns>true表示已注册,false表示尚未注册</returns>
 /// <param name="moduleName">模块名称.</param>
 public bool isModuleRegisted(string moduleName)
 {
     return(NativeUtils.isModuleRegisted(_nativeObjectId, moduleName));
 }
 /// <summary>
 /// 初始化
 /// </summary>
 public LuaScriptController()
 {
     _nativeObjectId = NativeUtils.createLuaScriptController();
 }
 /// <summary>
 /// 设置脚本执行超时时间
 /// </summary>
 /// <param name="timeout">单位:秒,设置0表示没有时间限制</param>
 public void setTimeout(int timeout)
 {
     NativeUtils.scriptControllerSetTimeout(_nativeObjectId, timeout);
 }
 /// <summary>
 /// 强制退出执行脚本
 /// </summary>
 public void forceExit()
 {
     NativeUtils.scriptControllerForceExit(_nativeObjectId);
 }
Example #23
0
        /// <summary>
        /// 异常时触发
        /// </summary>
        /// <param name="handler">事件处理器</param>
        public void onException(LuaExceptionHandler handler)
        {
            IntPtr fp = Marshal.GetFunctionPointerForDelegate(handler);

            NativeUtils.setExceptionHandler(_nativeObjectId, fp);
        }
Example #24
0
 /// <summary>
 /// 添加Lua的搜索路径,如果在采用require方法时无法导入其他路径脚本,可能是由于脚本文件的所在路径不在lua的搜索路径中。
 /// 可通过此方法进行添加。
 /// </summary>
 /// <param name="path">路径.</param>
 public void addSearchPath(string path)
 {
     NativeUtils.addSearchPath(_nativeObjectId, path + "/?.lua");
 }
Example #25
0
        /// <summary>
        /// 导出类型
        /// </summary>
        /// <param name="type">类型.</param>
        /// <param name="context">上下文对象.</param>
        public void exportType(Type t, LuaContext context)
        {
            LuaExportTypeAnnotation typeAnnotation     = Attribute.GetCustomAttribute(t, typeof(LuaExportTypeAnnotation), false) as LuaExportTypeAnnotation;
            LuaExportTypeAnnotation baseTypeAnnotation = Attribute.GetCustomAttribute(t.BaseType, typeof(LuaExportTypeAnnotation), false) as LuaExportTypeAnnotation;

            //获取导出的类/实例方法
            Dictionary <string, MethodInfo> exportClassMethods = new Dictionary <string, MethodInfo> ();
            List <string> exportClassMethodNames = new List <string> ();

            Dictionary <string, MethodInfo> exportInstanceMethods = new Dictionary <string, MethodInfo> ();
            List <string> exportInstanceMethodNames = new List <string> ();

            MethodInfo[] methods = t.GetMethods();
            foreach (MethodInfo m in methods)
            {
                if (m.IsPublic || (m.IsStatic && m.IsPublic))
                {
                    StringBuilder methodSignature = new StringBuilder();
                    foreach (ParameterInfo paramInfo in m.GetParameters())
                    {
                        Type paramType = paramInfo.ParameterType;
                        if (baseTypesMapping.ContainsKey(paramType))
                        {
                            methodSignature.Append(baseTypesMapping [paramType]);
                        }
                        else
                        {
                            methodSignature.Append("@");
                        }
                    }

                    string methodName = string.Format("{0}_{1}", m.Name, methodSignature.ToString());

                    if (m.IsStatic && m.IsPublic)
                    {
                        if (typeAnnotation != null &&
                            typeAnnotation.excludeExportClassMethodNames != null &&
                            Array.IndexOf(typeAnnotation.excludeExportClassMethodNames, m.Name) >= 0)
                        {
                            //为过滤方法
                            continue;
                        }

                        //静态和公开的方法会导出到Lua
                        exportClassMethodNames.Add(methodName);
                        exportClassMethods.Add(methodName, m);
                    }
                    else if (m.IsPublic)
                    {
                        if (typeAnnotation != null &&
                            typeAnnotation.excludeExportInstanceMethodNames != null &&
                            Array.IndexOf(typeAnnotation.excludeExportInstanceMethodNames, m.Name) >= 0)
                        {
                            //为过滤方法
                            continue;
                        }

                        //实例方法
                        exportInstanceMethodNames.Add(methodName);
                        exportInstanceMethods.Add(methodName, m);
                    }
                }
            }

            //获取导出的字段
            Dictionary <string, PropertyInfo> exportFields = new Dictionary <string, PropertyInfo> ();
            List <string> exportPropertyNames = new List <string> ();

            PropertyInfo[] propertys = t.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            foreach (PropertyInfo p in propertys)
            {
                if (typeAnnotation != null &&
                    typeAnnotation.excludeExportPropertyNames != null &&
                    Array.IndexOf(typeAnnotation.excludeExportPropertyNames, p.Name) >= 0)
                {
                    //在过滤列表中
                    continue;
                }

                StringBuilder actStringBuilder = new StringBuilder();
                if (p.CanRead)
                {
                    actStringBuilder.Append("r");
                }
                if (p.CanWrite)
                {
                    actStringBuilder.Append("w");
                }

                exportPropertyNames.Add(string.Format("{0}_{1}", p.Name, actStringBuilder.ToString()));
                exportFields.Add(p.Name, p);
            }

            //创建导出的字段数据
            IntPtr exportPropertyNamesPtr = IntPtr.Zero;

            if (exportPropertyNames.Count > 0)
            {
                LuaObjectEncoder fieldEncoder = new LuaObjectEncoder(context);
                fieldEncoder.writeInt32(exportPropertyNames.Count);
                foreach (string name in exportPropertyNames)
                {
                    fieldEncoder.writeString(name);
                }

                byte[] fieldNameBytes = fieldEncoder.bytes;
                exportPropertyNamesPtr = Marshal.AllocHGlobal(fieldNameBytes.Length);
                Marshal.Copy(fieldNameBytes, 0, exportPropertyNamesPtr, fieldNameBytes.Length);
            }


            //创建导出的实例方法数据
            IntPtr exportInstanceMethodNamesPtr = IntPtr.Zero;

            if (exportInstanceMethodNames.Count > 0)
            {
                LuaObjectEncoder instanceMethodEncoder = new LuaObjectEncoder(context);
                instanceMethodEncoder.writeInt32(exportInstanceMethodNames.Count);
                foreach (string name in exportInstanceMethodNames)
                {
                    instanceMethodEncoder.writeString(name);
                }

                byte[] instMethodNameBytes = instanceMethodEncoder.bytes;
                exportInstanceMethodNamesPtr = Marshal.AllocHGlobal(instMethodNameBytes.Length);
                Marshal.Copy(instMethodNameBytes, 0, exportInstanceMethodNamesPtr, instMethodNameBytes.Length);
            }


            //创建导出类方法数据
            IntPtr exportClassMethodNamesPtr = IntPtr.Zero;

            if (exportClassMethodNames.Count > 0)
            {
                LuaObjectEncoder classMethodEncoder = new LuaObjectEncoder(context);
                classMethodEncoder.writeInt32(exportClassMethodNames.Count);
                foreach (string name in exportClassMethodNames)
                {
                    classMethodEncoder.writeString(name);
                }

                byte[] classMethodNameBytes = classMethodEncoder.bytes;
                exportClassMethodNamesPtr = Marshal.AllocHGlobal(classMethodNameBytes.Length);
                Marshal.Copy(classMethodNameBytes, 0, exportClassMethodNamesPtr, classMethodNameBytes.Length);
            }

            //创建实例方法
            if (_createInstanceDelegate == null)
            {
                _createInstanceDelegate = new LuaInstanceCreateHandleDelegate(_createInstance);
            }

            //销毁实例方法
            if (_destroyInstanceDelegate == null)
            {
                _destroyInstanceDelegate = new LuaInstanceDestroyHandleDelegate(_destroyInstance);
            }

            //类描述
            if (_instanceDescriptionDelegate == null)
            {
                _instanceDescriptionDelegate = new LuaInstanceDescriptionHandleDelegate(_instanceDescription);
            }

            //字段获取器
            if (_fieldGetterDelegate == null)
            {
                _fieldGetterDelegate = new LuaInstanceFieldGetterHandleDelegate(_fieldGetter);
            }

            //字段设置器
            if (_fieldSetterDelegate == null)
            {
                _fieldSetterDelegate = new LuaInstanceFieldSetterHandleDelegate(_fieldSetter);
            }

            //实例方法处理器
            if (_instanceMethodHandlerDelegate == null)
            {
                _instanceMethodHandlerDelegate = new LuaInstanceMethodHandleDelegate(_instanceMethodHandler);
            }

            //类方法处理器
            if (_classMethodHandleDelegate == null)
            {
                _classMethodHandleDelegate = new LuaModuleMethodHandleDelegate(_classMethodHandler);
            }

            string typeName = t.Name;

            if (typeAnnotation != null && typeAnnotation.typeName != null)
            {
                typeName = typeAnnotation.typeName;
            }

            string baseTypeName = t.BaseType.Name;

            if (baseTypeAnnotation != null && baseTypeAnnotation.typeName != null)
            {
                baseTypeName = baseTypeAnnotation.typeName;
            }

            int typeId = NativeUtils.registerType(
                context.objectId,
                typeName,
                baseTypeName,
                exportPropertyNamesPtr,
                exportInstanceMethodNamesPtr,
                exportClassMethodNamesPtr,
                Marshal.GetFunctionPointerForDelegate(_createInstanceDelegate),
                Marshal.GetFunctionPointerForDelegate(_destroyInstanceDelegate),
                Marshal.GetFunctionPointerForDelegate(_instanceDescriptionDelegate),
                Marshal.GetFunctionPointerForDelegate(_fieldGetterDelegate),
                Marshal.GetFunctionPointerForDelegate(_fieldSetterDelegate),
                Marshal.GetFunctionPointerForDelegate(_instanceMethodHandlerDelegate),
                Marshal.GetFunctionPointerForDelegate(_classMethodHandleDelegate));

            //关联注册模块的注册方法
            _exportsClass[typeId]           = t;
            _exportsClassIdMapping [t]      = typeId;
            _exportsClassMethods[typeId]    = exportClassMethods;
            _exportsInstanceMethods[typeId] = exportInstanceMethods;
            _exportsFields[typeId]          = exportFields;

            if (exportPropertyNamesPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(exportPropertyNamesPtr);
            }
            if (exportInstanceMethodNamesPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(exportInstanceMethodNamesPtr);
            }
            if (exportClassMethodNamesPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(exportClassMethodNamesPtr);
            }
        }