2023-11-21 23:05:03 +08:00

282 lines
5.7 KiB
C#

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);
}
}
}
}