using System; using System.ComponentModel; using System.Runtime.InteropServices; namespace MultiWheelC.TrajectoryPlanning.EMPlanner; internal static class OsqpNativeMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr VersionDelegate(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SetDefaultSettingsDelegate(IntPtr settings); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate int SetupDelegate( out IntPtr solver, IntPtr upperTriangularP, IntPtr linearCost, IntPtr constraints, IntPtr lowerBounds, IntPtr upperBounds, int constraintCount, int variableCount, IntPtr settings); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate int WarmStartDelegate(IntPtr solver, IntPtr primal, IntPtr dual); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate int SolveDelegate(IntPtr solver); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate int CleanupDelegate(IntPtr solver); public static IntPtr LoadLibrary(string absolutePath) { return LoadLibraryW(absolutePath); } public static bool FreeModule(IntPtr moduleHandle) { return FreeLibrary(moduleHandle); } public static string LastErrorMessage() { int error = Marshal.GetLastWin32Error(); return new Win32Exception(error).Message; } public static OsqpNativeApi ResolveApi(IntPtr moduleHandle) { return new OsqpNativeApi( Resolve(moduleHandle, "osqp_version"), Resolve(moduleHandle, "osqp_set_default_settings"), Resolve(moduleHandle, "osqp_setup"), Resolve(moduleHandle, "osqp_warm_start"), Resolve(moduleHandle, "osqp_solve"), Resolve(moduleHandle, "osqp_cleanup")); } private static T Resolve(IntPtr moduleHandle, string exportName) where T : Delegate { IntPtr procedure = GetProcAddress(moduleHandle, exportName); if (procedure == IntPtr.Zero) throw new InvalidOperationException("Missing OSQP export " + exportName + "."); return Marshal.GetDelegateForFunctionPointer(procedure); } [DllImport("kernel32", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] private static extern IntPtr LoadLibraryW(string fileName); [DllImport("kernel32", ExactSpelling = true, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool FreeLibrary(IntPtr moduleHandle); [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] private static extern IntPtr GetProcAddress(IntPtr moduleHandle, string procedureName); } internal sealed class OsqpNativeApi { public OsqpNativeApi( OsqpNativeMethods.VersionDelegate version, OsqpNativeMethods.SetDefaultSettingsDelegate setDefaultSettings, OsqpNativeMethods.SetupDelegate setup, OsqpNativeMethods.WarmStartDelegate warmStart, OsqpNativeMethods.SolveDelegate solve, OsqpNativeMethods.CleanupDelegate cleanup) { Version = version; SetDefaultSettings = setDefaultSettings; Setup = setup; WarmStart = warmStart; Solve = solve; Cleanup = cleanup; } public OsqpNativeMethods.VersionDelegate Version { get; } public OsqpNativeMethods.SetDefaultSettingsDelegate SetDefaultSettings { get; } public OsqpNativeMethods.SetupDelegate Setup { get; } public OsqpNativeMethods.WarmStartDelegate WarmStart { get; } public OsqpNativeMethods.SolveDelegate Solve { get; } public OsqpNativeMethods.CleanupDelegate Cleanup { get; } }