-
Notifications
You must be signed in to change notification settings - Fork 750
Get the correct library loading functions at runtime #894
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next
Next commit
Get the correct library loading functions at runtime
- Loading branch information
commit 1dd2ee1b02449b85eeee6120c88a4092dc78851a
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
using System; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace Python.Runtime.Platform | ||
{ | ||
interface ILibraryLoader | ||
{ | ||
IntPtr Load(string dllToLoad); | ||
|
||
IntPtr GetFunction(IntPtr hModule, string procedureName); | ||
|
||
bool Free(IntPtr hModule); | ||
} | ||
|
||
static class LibraryLoader | ||
{ | ||
public static ILibraryLoader Get(OperatingSystemType os) | ||
{ | ||
switch (os) | ||
{ | ||
case OperatingSystemType.Windows: | ||
return new WindowsLoader(); | ||
case OperatingSystemType.Darwin: | ||
return new DarwinLoader(); | ||
case OperatingSystemType.Linux: | ||
return new LinuxLoader(); | ||
default: | ||
throw new Exception($"This operating system ({os}) is not supported"); | ||
} | ||
} | ||
} | ||
|
||
class LinuxLoader : ILibraryLoader | ||
{ | ||
private static int RTLD_NOW = 0x2; | ||
filmor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
private static int RTLD_GLOBAL = 0x100; | ||
private static IntPtr RTLD_DEFAULT = IntPtr.Zero; | ||
private const string NativeDll = "libdl.so"; | ||
|
||
public IntPtr Load(string fileName) | ||
{ | ||
return dlopen($"lib{fileName}.so", RTLD_NOW | RTLD_GLOBAL); | ||
filmor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
public bool Free(IntPtr handle) | ||
{ | ||
dlclose(handle); | ||
return true; | ||
} | ||
|
||
public IntPtr GetFunction(IntPtr dllHandle, string name) | ||
{ | ||
// look in the exe if dllHandle is NULL | ||
if (dllHandle == IntPtr.Zero) | ||
{ | ||
dllHandle = RTLD_DEFAULT; | ||
} | ||
|
||
// clear previous errors if any | ||
dlerror(); | ||
IntPtr res = dlsym(dllHandle, name); | ||
IntPtr errPtr = dlerror(); | ||
if (errPtr != IntPtr.Zero) | ||
{ | ||
throw new Exception("dlsym: " + Marshal.PtrToStringAnsi(errPtr)); | ||
} | ||
return res; | ||
} | ||
|
||
[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] | ||
public static extern IntPtr dlopen(String fileName, int flags); | ||
|
||
[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] | ||
private static extern IntPtr dlsym(IntPtr handle, String symbol); | ||
|
||
[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl)] | ||
private static extern int dlclose(IntPtr handle); | ||
|
||
[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl)] | ||
private static extern IntPtr dlerror(); | ||
} | ||
|
||
class DarwinLoader : ILibraryLoader | ||
{ | ||
private static int RTLD_NOW = 0x2; | ||
private static int RTLD_GLOBAL = 0x8; | ||
private const string NativeDll = "/usr/lib/libSystem.dylib"; | ||
private static IntPtr RTLD_DEFAULT = new IntPtr(-2); | ||
|
||
public IntPtr Load(string fileName) | ||
{ | ||
return dlopen($"lib{fileName}.dylib", RTLD_NOW | RTLD_GLOBAL); | ||
filmor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
public bool Free(IntPtr handle) | ||
{ | ||
dlclose(handle); | ||
return true; | ||
} | ||
|
||
public IntPtr GetFunction(IntPtr dllHandle, string name) | ||
{ | ||
// look in the exe if dllHandle is NULL | ||
if (dllHandle == IntPtr.Zero) | ||
{ | ||
dllHandle = RTLD_DEFAULT; | ||
} | ||
|
||
// clear previous errors if any | ||
dlerror(); | ||
IntPtr res = dlsym(dllHandle, name); | ||
IntPtr errPtr = dlerror(); | ||
if (errPtr != IntPtr.Zero) | ||
{ | ||
throw new Exception("dlsym: " + Marshal.PtrToStringAnsi(errPtr)); | ||
filmor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
return res; | ||
} | ||
|
||
[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] | ||
public static extern IntPtr dlopen(String fileName, int flags); | ||
|
||
[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] | ||
private static extern IntPtr dlsym(IntPtr handle, String symbol); | ||
|
||
[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl)] | ||
private static extern int dlclose(IntPtr handle); | ||
|
||
[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl)] | ||
private static extern IntPtr dlerror(); | ||
} | ||
|
||
class WindowsLoader : ILibraryLoader | ||
{ | ||
private const string NativeDll = "kernel32.dll"; | ||
|
||
[DllImport(NativeDll)] | ||
static extern IntPtr LoadLibrary(string dllToLoad); | ||
|
||
public IntPtr Load(string dllToLoad) => WindowsLoader.LoadLibrary(dllToLoad); | ||
filmor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
[DllImport(NativeDll)] | ||
static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); | ||
|
||
public IntPtr GetFunction(IntPtr hModule, string procedureName) => WindowsLoader.GetProcAddress(hModule, procedureName); | ||
filmor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
[DllImport(NativeDll)] | ||
static extern bool FreeLibrary(IntPtr hModule); | ||
|
||
public bool Free(IntPtr hModule) => WindowsLoader.FreeLibrary(hModule); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
namespace Python.Runtime.Platform | ||
{ | ||
public enum MachineType | ||
{ | ||
i386, | ||
x86_64, | ||
armv7l, | ||
armv8, | ||
Other | ||
}; | ||
|
||
/// <summary> | ||
/// Operating system type as reported by Python. | ||
/// </summary> | ||
public enum OperatingSystemType | ||
{ | ||
Windows, | ||
Darwin, | ||
Linux, | ||
Other | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.