#pragma warning disable IDE1006 // Naming Styles (interface for native functions) using System; using System.Runtime.InteropServices; namespace Python.Runtime.Platform { interface ILibDL { IntPtr dlopen(string? fileName, int flags); IntPtr dlsym(IntPtr handle, string symbol); int dlclose(IntPtr handle); IntPtr dlerror(); int RTLD_NOW { get; } int RTLD_GLOBAL { get; } IntPtr RTLD_DEFAULT { get; } } class LinuxLibDL : ILibDL { private const string NativeDll = "libdl.so"; public int RTLD_NOW => 0x2; public int RTLD_GLOBAL => 0x100; public IntPtr RTLD_DEFAULT => IntPtr.Zero; public static ILibDL GetInstance() { try { ILibDL libdl2 = new LinuxLibDL2(); // call dlerror to ensure library is resolved libdl2.dlerror(); return libdl2; } catch (DllNotFoundException) { return new LinuxLibDL(); } } IntPtr ILibDL.dlopen(string? fileName, int flags) => dlopen(fileName, flags); IntPtr ILibDL.dlsym(IntPtr handle, string symbol) => dlsym(handle, symbol); int ILibDL.dlclose(IntPtr handle) => dlclose(handle); IntPtr ILibDL.dlerror() => dlerror(); [DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private 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 LinuxLibDL2 : ILibDL { private const string NativeDll = "libdl.so.2"; public int RTLD_NOW => 0x2; public int RTLD_GLOBAL => 0x100; public IntPtr RTLD_DEFAULT => IntPtr.Zero; IntPtr ILibDL.dlopen(string? fileName, int flags) => dlopen(fileName, flags); IntPtr ILibDL.dlsym(IntPtr handle, string symbol) => dlsym(handle, symbol); int ILibDL.dlclose(IntPtr handle) => dlclose(handle); IntPtr ILibDL.dlerror() => dlerror(); [DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private 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 MacLibDL : ILibDL { public int RTLD_NOW => 0x2; public int RTLD_GLOBAL => 0x8; const string NativeDll = "/usr/lib/libSystem.dylib"; public IntPtr RTLD_DEFAULT => new(-2); IntPtr ILibDL.dlopen(string? fileName, int flags) => dlopen(fileName, flags); IntPtr ILibDL.dlsym(IntPtr handle, string symbol) => dlsym(handle, symbol); int ILibDL.dlclose(IntPtr handle) => dlclose(handle); IntPtr ILibDL.dlerror() => dlerror(); [DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private 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(); } }