using CPF.Mac.CoreFoundation; using CPF.Mac.Foundation; using System; using System.Runtime.InteropServices; namespace CPF.Mac.ObjCRuntime { public static class Dlfcn { [DllImport("/usr/lib/libSystem.dylib")] public static extern int dlclose(IntPtr handle); [DllImport("/usr/lib/libSystem.dylib")] public static extern IntPtr dlopen(string path, int mode); [DllImport("/usr/lib/libSystem.dylib")] public static extern IntPtr dlsym(IntPtr handle, string symbol); [DllImport("/usr/lib/libSystem.dylib", EntryPoint = "dlerror")] internal static extern IntPtr dlerror_(); public static string dlerror() { return Marshal.PtrToStringAnsi(dlerror_()); } public static NSString GetStringConstant(IntPtr handle, string symbol) { IntPtr intPtr = dlsym(handle, symbol); if (intPtr == IntPtr.Zero) { return null; } IntPtr intPtr2 = Marshal.ReadIntPtr(intPtr); if (intPtr2 == IntPtr.Zero) { return null; } return (NSString)Runtime.GetNSObject(intPtr2); } public static IntPtr GetIndirect(IntPtr handle, string symbol) { return dlsym(handle, symbol); } public static NSNumber GetNSNumber(IntPtr handle, string symbol) { IntPtr intPtr = dlsym(handle, symbol); if (intPtr == IntPtr.Zero) { return null; } IntPtr intPtr2 = Marshal.ReadIntPtr(intPtr); if (intPtr2 == IntPtr.Zero) { return null; } return (NSNumber)Runtime.GetNSObject(intPtr2); } public static int GetInt32(IntPtr handle, string symbol) { IntPtr intPtr = dlsym(handle, symbol); if (intPtr == IntPtr.Zero) { return 0; } return Marshal.ReadInt32(intPtr); } public static void SetInt32(IntPtr handle, string symbol, int value) { IntPtr intPtr = dlsym(handle, symbol); if (!(intPtr == IntPtr.Zero)) { Marshal.WriteInt32(intPtr, value); } } public static long GetInt64(IntPtr handle, string symbol) { IntPtr intPtr = dlsym(handle, symbol); if (intPtr == IntPtr.Zero) { return 0L; } return Marshal.ReadInt64(intPtr); } public static void SetInt64(IntPtr handle, string symbol, long value) { IntPtr intPtr = dlsym(handle, symbol); if (!(intPtr == IntPtr.Zero)) { Marshal.WriteInt64(intPtr, value); } } public static void SetString(IntPtr handle, string symbol, string value) { IntPtr intPtr = dlsym(handle, symbol); if (!(intPtr == IntPtr.Zero)) { Marshal.WriteIntPtr(intPtr, (value == null) ? IntPtr.Zero : NSString.CreateNative(value)); } } public static void SetString(IntPtr handle, string symbol, NSString value) { IntPtr intPtr = dlsym(handle, symbol); if (!(intPtr == IntPtr.Zero)) { IntPtr intPtr2 = (value == null) ? IntPtr.Zero : value.Handle; if (intPtr2 != IntPtr.Zero) { CFObject.CFRetain(intPtr2); } Marshal.WriteIntPtr(intPtr, intPtr2); } } public static void SetArray(IntPtr handle, string symbol, NSArray array) { IntPtr intPtr = dlsym(handle, symbol); if (!(intPtr == IntPtr.Zero)) { IntPtr intPtr2 = array?.Handle ?? IntPtr.Zero; if (intPtr2 != IntPtr.Zero) { CFObject.CFRetain(intPtr2); } Marshal.WriteIntPtr(intPtr, intPtr2); } } public static IntPtr GetIntPtr(IntPtr handle, string symbol) { IntPtr intPtr = dlsym(handle, symbol); if (intPtr == IntPtr.Zero) { return IntPtr.Zero; } return Marshal.ReadIntPtr(intPtr); } public static void SetIntPtr(IntPtr handle, string symbol, IntPtr value) { IntPtr intPtr = dlsym(handle, symbol); if (!(intPtr == IntPtr.Zero)) { Marshal.WriteIntPtr(intPtr, value); } } public unsafe static double GetDouble(IntPtr handle, string symbol) { IntPtr intPtr = dlsym(handle, symbol); if (intPtr == IntPtr.Zero) { return 0.0; } double* ptr = (double*)(void*)intPtr; return *ptr; } public unsafe static void SetDouble(IntPtr handle, string symbol, double value) { IntPtr intPtr = dlsym(handle, symbol); if (!(intPtr == IntPtr.Zero)) { *(double*)(void*)intPtr = value; } } public unsafe static float GetFloat(IntPtr handle, string symbol) { IntPtr intPtr = dlsym(handle, symbol); if (intPtr == IntPtr.Zero) { return 0f; } float* ptr = (float*)(void*)intPtr; return *ptr; } public unsafe static void SetFloat(IntPtr handle, string symbol, float value) { IntPtr intPtr = dlsym(handle, symbol); if (!(intPtr == IntPtr.Zero)) { *(float*)(void*)intPtr = value; } } internal static int SlowGetInt32(string lib, string symbol) { IntPtr intPtr = dlopen(lib, 0); if (intPtr == IntPtr.Zero) { return 0; } try { return GetInt32(intPtr, symbol); } finally { dlclose(intPtr); } } internal static long SlowGetInt64(string lib, string symbol) { IntPtr intPtr = dlopen(lib, 0); if (intPtr == IntPtr.Zero) { return 0L; } try { return GetInt64(intPtr, symbol); } finally { dlclose(intPtr); } } internal static IntPtr SlowGetIntPtr(string lib, string symbol) { IntPtr intPtr = dlopen(lib, 0); if (intPtr == IntPtr.Zero) { return IntPtr.Zero; } try { return GetIntPtr(intPtr, symbol); } finally { dlclose(intPtr); } } internal static double SlowGetDouble(string lib, string symbol) { IntPtr intPtr = dlopen(lib, 0); if (intPtr == IntPtr.Zero) { return 0.0; } try { return GetDouble(intPtr, symbol); } finally { dlclose(intPtr); } } internal static NSString SlowGetStringConstant(string lib, string symbol) { IntPtr intPtr = dlopen(lib, 0); if (intPtr == IntPtr.Zero) { return null; } try { return GetStringConstant(intPtr, symbol); } finally { dlclose(intPtr); } } } }