This repository has been archived by the owner on Mar 13, 2024. It is now read-only.
forked from ryancheung/MonoGame.IMEHelper
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFuncLoader.Desktop.cs
114 lines (92 loc) · 3.76 KB
/
FuncLoader.Desktop.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#if !WINDOWSDX
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace MonoGame.IMEHelper
{
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 LoadLibraryExt(string libname)
{
var ret = IntPtr.Zero;
var assemblyLocation = Path.GetDirectoryName(typeof(FuncLoader).Assembly.Location) ?? "./";
// Try .NET Framework / mono locations
if (CurrentPlatform.OS == OS.MacOSX)
{
ret = LoadLibrary(Path.Combine(assemblyLocation, libname));
// Look in Frameworks for .app bundles
if (ret == IntPtr.Zero)
ret = LoadLibrary(Path.Combine(assemblyLocation, "..", "Frameworks", libname));
}
else
{
if (Environment.Is64BitProcess)
ret = LoadLibrary(Path.Combine(assemblyLocation, "x64", libname));
else
ret = LoadLibrary(Path.Combine(assemblyLocation, "x86", libname));
}
// Try .NET Core development locations
if (ret == IntPtr.Zero)
ret = LoadLibrary(Path.Combine(assemblyLocation, "runtimes", CurrentPlatform.Rid, "native", libname));
// Try current folder (.NET Core will copy it there after publish) or system library
if (ret == IntPtr.Zero)
ret = LoadLibrary(libname);
// Welp, all failed, PANIC!!!
if (ret == IntPtr.Zero)
throw new Exception("Failed to load library: " + libname);
return ret;
}
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
}
}
}
#endif