Files
LuaCsForBarotraumaEP/Libraries/MonoGame.Framework/Src/MonoGame.Framework/Utilities/FuncLoader.Desktop.cs
2019-06-25 16:00:44 +03:00

75 lines
2.3 KiB
C#

using System;
using System.Runtime.InteropServices;
namespace MonoGame.Utilities
{
internal class FuncLoader
{
private class Windows
{
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibraryW(string lpszLib);
}
private class Linux
{
[DllImport("libdl.so.2")]
public static extern IntPtr dlopen(string path, int flags);
[DllImport("libdl.so.2")]
public static extern IntPtr dlsym(IntPtr handle, string symbol);
}
private class OSX
{
[DllImport("/usr/lib/libSystem.dylib")]
public static extern IntPtr dlopen(string path, int flags);
[DllImport("/usr/lib/libSystem.dylib")]
public static extern IntPtr dlsym(IntPtr handle, string symbol);
}
private const int RTLD_LAZY = 0x0001;
public static IntPtr LoadLibrary(string libname)
{
if (CurrentPlatform.OS == OS.Windows)
return Windows.LoadLibraryW(libname);
if (CurrentPlatform.OS == OS.MacOSX)
return OSX.dlopen(libname, RTLD_LAZY);
return Linux.dlopen(libname, RTLD_LAZY);
}
public static T LoadFunction<T>(IntPtr library, string function, bool throwIfNotFound = false)
{
var ret = IntPtr.Zero;
if (CurrentPlatform.OS == OS.Windows)
ret = Windows.GetProcAddress(library, function);
else if (CurrentPlatform.OS == OS.MacOSX)
ret = OSX.dlsym(library, function);
else
ret = Linux.dlsym(library, function);
if (ret == IntPtr.Zero)
{
if (throwIfNotFound)
throw new EntryPointNotFoundException(function);
return default(T);
}
#if NETSTANDARD
return Marshal.GetDelegateForFunctionPointer<T>(ret);
#else
return (T)(object)Marshal.GetDelegateForFunctionPointer(ret, typeof(T));
#endif
}
}
}