Use a DLIR for Mupen core and plugins

AttachPlugin still returns IntPtr (thanks to reflection hack) so the code for
audio/input/video is unaffected
This commit is contained in:
YoshiRulz 2020-07-28 20:24:54 +10:00
parent 771621e0c9
commit fbb38d61fd
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
1 changed files with 18 additions and 27 deletions

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
@ -27,8 +28,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
bool event_frameend = false; bool event_frameend = false;
bool event_breakpoint = false; bool event_breakpoint = false;
private static readonly OSTailoredCode.ILinkedLibManager libLoader = OSTailoredCode.LinkedLibManager;
public enum m64p_error public enum m64p_error
{ {
M64ERR_SUCCESS = 0, M64ERR_SUCCESS = 0,
@ -471,8 +470,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
delegate m64p_error DebugStep(); delegate m64p_error DebugStep();
DebugStep m64pDebugStep; DebugStep m64pDebugStep;
// DLL handles private readonly DynamicLibraryImportResolver Library = new DynamicLibraryImportResolver(OSTailoredCode.IsUnixHost ? "libmupen64plus.so.2" : "mupen64plus.dll");
public IntPtr CoreDll { get; }
public mupen64plusApi(N64 bizhawkCore, byte[] rom, VideoPluginSettings video_settings, int SaveType, int CoreType, bool DisableExpansionSlot) public mupen64plusApi(N64 bizhawkCore, byte[] rom, VideoPluginSettings video_settings, int SaveType, int CoreType, bool DisableExpansionSlot)
{ {
@ -484,8 +482,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
} }
this.bizhawkCore = bizhawkCore; this.bizhawkCore = bizhawkCore;
CoreDll = libLoader.LoadOrThrow("mupen64plus");
connectFunctionPointers(); connectFunctionPointers();
// Start up the core // Start up the core
@ -576,14 +572,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
cb.GetType(); cb.GetType();
} }
internal static T GetTypedDelegate<T>(IntPtr lib, string proc) where T : Delegate => (T) Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddrOrThrow(lib, proc), typeof(T)); internal static T GetTypedDelegate<T>(IntPtr lib, string proc) where T : Delegate => (T) Marshal.GetDelegateForFunctionPointer(OSTailoredCode.LinkedLibManager.GetProcAddrOrThrow(lib, proc), typeof(T));
/// <summary> /// <summary>
/// Look up function pointers in the dlls /// Look up function pointers in the dlls
/// </summary> /// </summary>
void connectFunctionPointers() void connectFunctionPointers()
{ {
T GetCoreDelegate<T>(string proc) where T : Delegate => GetTypedDelegate<T>(CoreDll, proc); T GetCoreDelegate<T>(string proc) where T : Delegate => (T) Marshal.GetDelegateForFunctionPointer(Library.GetProcAddrOrThrow(proc), typeof(T));
m64pCoreStartup = GetCoreDelegate<CoreStartup>("CoreStartup"); m64pCoreStartup = GetCoreDelegate<CoreStartup>("CoreStartup");
m64pCoreShutdown = GetCoreDelegate<CoreShutdown>("CoreShutdown"); m64pCoreShutdown = GetCoreDelegate<CoreShutdown>("CoreShutdown");
@ -969,40 +965,35 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
m64pCoreDoCommandPtr(m64p_command.M64CMD_ROM_CLOSE, 0, IntPtr.Zero); m64pCoreDoCommandPtr(m64p_command.M64CMD_ROM_CLOSE, 0, IntPtr.Zero);
m64pCoreShutdown(); m64pCoreShutdown();
libLoader.FreeByPtr(CoreDll); Library.Dispose();
disposed = true; disposed = true;
} }
} }
private static readonly FieldInfo fiDLIRInternalPtr = typeof(DynamicLibraryImportResolver).GetField("_p", BindingFlags.Instance | BindingFlags.NonPublic);
struct AttachedPlugin struct AttachedPlugin
{ {
public PluginStartup dllStartup; public DynamicLibraryImportResolver dllThinWrapper;
public PluginShutdown dllShutdown; public PluginShutdown dllShutdown;
public IntPtr dllHandle;
} }
Dictionary<m64p_plugin_type, AttachedPlugin> plugins = new Dictionary<m64p_plugin_type, AttachedPlugin>(); Dictionary<m64p_plugin_type, AttachedPlugin> plugins = new Dictionary<m64p_plugin_type, AttachedPlugin>();
public IntPtr AttachPlugin(m64p_plugin_type type, string PluginName) public IntPtr AttachPlugin(m64p_plugin_type type, string PluginName)
{ {
if (plugins.ContainsKey(type)) static IntPtr GetDLIRPtrByRefl(DynamicLibraryImportResolver dlir) => (IntPtr) fiDLIRInternalPtr.GetValue(dlir);
DetachPlugin(type); if (plugins.ContainsKey(type)) DetachPlugin(type);
var lib = new DynamicLibraryImportResolver(PluginName);
AttachedPlugin plugin; var libPtr = GetDLIRPtrByRefl(lib);
plugin.dllHandle = libLoader.LoadOrThrow(PluginName); GetTypedDelegate<PluginStartup>(libPtr, "PluginStartup")(GetDLIRPtrByRefl(Library), null, null);
plugin.dllStartup = GetTypedDelegate<PluginStartup>(plugin.dllHandle, "PluginStartup"); if (m64pCoreAttachPlugin(type, libPtr) != m64p_error.M64ERR_SUCCESS)
plugin.dllShutdown = GetTypedDelegate<PluginShutdown>(plugin.dllHandle, "PluginShutdown");
plugin.dllStartup(CoreDll, null, null);
m64p_error result = m64pCoreAttachPlugin(type, plugin.dllHandle);
if (result != m64p_error.M64ERR_SUCCESS)
{ {
libLoader.FreeByPtr(plugin.dllHandle); lib.Dispose();
throw new InvalidOperationException($"Error during attaching plugin {PluginName}"); throw new InvalidOperationException($"Error during attaching plugin {PluginName}");
} }
plugins.Add(type, new AttachedPlugin { dllThinWrapper = lib, dllShutdown = GetTypedDelegate<PluginShutdown>(libPtr, "PluginShutdown") });
plugins.Add(type, plugin); return libPtr;
return plugin.dllHandle;
} }
public void DetachPlugin(m64p_plugin_type type) public void DetachPlugin(m64p_plugin_type type)
@ -1012,7 +1003,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
plugins.Remove(type); plugins.Remove(type);
m64pCoreDetachPlugin(type); m64pCoreDetachPlugin(type);
plugin.dllShutdown(); plugin.dllShutdown();
libLoader.FreeByPtr(plugin.dllHandle); plugin.dllThinWrapper.Dispose();
} }
} }