feat: load pinned OSQP native library
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
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<VersionDelegate>(moduleHandle, "osqp_version"),
|
||||
Resolve<SetDefaultSettingsDelegate>(moduleHandle, "osqp_set_default_settings"),
|
||||
Resolve<SetupDelegate>(moduleHandle, "osqp_setup"),
|
||||
Resolve<WarmStartDelegate>(moduleHandle, "osqp_warm_start"),
|
||||
Resolve<SolveDelegate>(moduleHandle, "osqp_solve"),
|
||||
Resolve<CleanupDelegate>(moduleHandle, "osqp_cleanup"));
|
||||
}
|
||||
|
||||
private static T Resolve<T>(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<T>(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; }
|
||||
}
|
||||
Reference in New Issue
Block a user