// Methods private void Awake() { #if UNITY_EDITOR if (_singleton != null) { Debug.LogError( string.Format("Created multiple NativePluginLoader objects. Destroying duplicate created on GameObject [{0}]", gameObject.name)); Destroy(this); return; } _singleton = this; DontDestroyOnLoad(gameObject); DirectoryInfo parentDirectory = Directory.GetParent(Application.dataPath); string parentDirectoryStr = parentDirectory.FullName; _path = parentDirectoryStr + "\\Resources\\Plugins\\"; if (SystemLibrary.SetDllDirectory(_path)) { LoadAll(); } else { Debug.Assert(false, "Could not set the dll directory path correctly, maybe the folder does not exist, please make sure the path exist!"); } #endif }
// Free all loaded libraries void UnloadAll() { foreach (var kvp in _loadedPlugins) { bool result = SystemLibrary.FreeLibrary(kvp.Value); } _loadedPlugins.Clear(); }
// Free all loaded libraries private void UnloadAll() { foreach (KeyValuePair <string, IntPtr> kvp in _loadedPlugins) { bool result = SystemLibrary.FreeLibrary(kvp.Value); } _loadedPlugins.Clear(); }
// Load all plugins with 'PluginAttr' // Load all functions with 'PluginFunctionAttr' void LoadAll() { // TODO: Could loop over just Assembly-CSharp.dll in most cases? // Loop over all assemblies var assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) { // Loop over all types foreach (var type in assembly.GetTypes()) { // Get custom attributes for type var typeAttributes = type.GetCustomAttributes(typeof(PluginAttr), true); if (typeAttributes.Length > 0) { Debug.Assert(typeAttributes.Length == 1); // should not be possible var typeAttribute = typeAttributes[0] as PluginAttr; var pluginName = typeAttribute.pluginName; IntPtr pluginHandle = IntPtr.Zero; if (!_loadedPlugins.TryGetValue(pluginName, out pluginHandle)) { var pluginPath = _path + pluginName + EXT; pluginHandle = SystemLibrary.LoadLibrary(pluginPath); if (pluginHandle == IntPtr.Zero) { throw new System.Exception("Failed to load plugin [" + pluginPath + "]"); } _loadedPlugins.Add(pluginName, pluginHandle); } // Loop over fields in type var fields = type.GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public); foreach (var field in fields) { // Get custom attributes for field var fieldAttributes = field.GetCustomAttributes(typeof(PluginFunctionAttr), true); if (fieldAttributes.Length > 0) { Debug.Assert(fieldAttributes.Length == 1); // should not be possible // Get PluginFunctionAttr attribute var fieldAttribute = fieldAttributes[0] as PluginFunctionAttr; var functionName = fieldAttribute.functionName; // Get function pointer var fnPtr = SystemLibrary.GetProcAddress(pluginHandle, functionName); if (fnPtr == IntPtr.Zero) { Debug.LogError(string.Format("Failed to find function [{0}] in plugin [{1}]. Err: [{2}]", functionName, pluginName, SystemLibrary.GetLastError())); continue; } // Get delegate pointer var fnDelegate = Marshal.GetDelegateForFunctionPointer(fnPtr, field.FieldType); // Set static field value field.SetValue(null, fnDelegate); } } } } } }