using System; using System.Runtime.InteropServices; using System.Reflection; namespace Quik.Stb { public unsafe static partial class Stbtt { private delegate void FailedAssertProc(byte *expression, byte *file, int line, byte *function); private static readonly string[] LibraryNames = new string[] { //FIXME: This is wrong on so many levels, but, i need to do this // in order to get a change of this running. "runtimes/win-x64/native/libstbtt.dll", "runtimes/win-x86/native/libstbtt.dll", "runtimes/linux-arm/native/libstbtt.so", "runtimes/linux-arm64/native/libstbtt.so", "runtimes/linux-x64/native/libstbtt.so", "runtimes/native/libstbtt.dylib", "libstbtt.dll", "libstbtt.so", "libstbtt.dylib", }; static Stbtt() { NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), Resolver); quik_stbtt_failed_assert_store(Marshal.GetFunctionPointerForDelegate(FailedAssert)); } private static IntPtr Resolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath) { if (libraryName != "stbtt") return IntPtr.Zero; foreach (string name in LibraryNames) { if (NativeLibrary.TryLoad(name, assembly, searchPath, out IntPtr handle)) { return handle; } } return NativeLibrary.Load(libraryName); } private static void FailedAssert(byte *expression, byte *file, int line, byte *function) { string expr = expression == null ? string.Empty : Marshal.PtrToStringUTF8((IntPtr)expression); string f = file == null ? string.Empty : Marshal.PtrToStringUTF8((IntPtr)file); string func = function == null ? string.Empty : Marshal.PtrToStringUTF8((IntPtr)function); Exception ex = new Exception($"Assert failed in native stbtt code. ({System.IO.Path.GetFileName(f)}:{line})"); ex.Data.Add("Expression", expr); ex.Data.Add("File", f); ex.Data.Add("Line", line); ex.Data.Add("Function", func); throw ex; } } }