Files
sbox-public/engine/Sandbox.Engine/Platform/DLLImportResolver.cs
Sam Pavlovic 73a5d11304 Unix Launch Fixes (#4304)
* Gitignore for unix objects and bins

* libmpg123 mac

* try with kosmiskrisp instead of molten xx, much less problematic?

* Explicit cast for box3d and include for utlblockmemory to make clang happ

* Simple DLLImportResolver for the 3 platforms, on linux/mac it tries to load DLLs from managed/ directory even with PATH being set, and backport the steamworks behaviour from Facepunch.Steamwokrs

* Dont ShaderCompile outside of tools, resourcecompiler is not even enabled there

* Only enable steam audio binaural effect on windows, we self compile it with that feature on there, dont bother yet for linux/mac until we have a better way to do dependency track

* Fix DLLImportResolver, also let's try to keep just a single set of binaries for managed without platform variants

* Fix rect_t interop on ARM64

On ARM64, NativeRect (4 floats = HFA) gets passed in float registers (v0-v3), but the C++ function reads from x1 expecting a pointer → null crash.
On x64 Windows, passing a 16-byte struct "by value" through an unmanaged function pointer accidentally works because the x64 ABI passes it by hidden pointer anyway. On ARM64, NativeRect (4 floats = HFA) goes into float registers v0-v3, leaving x1=0x0 for the C++ Rect_t* parameter.

* Building the load path via string interpolation hardcodes "/" and can produce double-separators because NetCore.NativeDllPath already includes a trailing slash. For consistency with the rest of the codebase (e.g., InteropGen uses Path.Combine with NativeDllPath) and to avoid path quirks across platforms, use Path.Combine(NetCore.NativeDllPath, nativeName).

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Format

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-25 16:08:21 +01:00

58 lines
1.7 KiB
C#

using System.Reflection;
using System.Runtime.InteropServices;
using System.IO;
namespace Sandbox;
internal static class DLLImportResolver
{
private static readonly HashSet<string> registeredAssemblies = new();
internal static void SetupResolvers()
{
// Register for all currently loaded assemblies
foreach ( var assembly in AppDomain.CurrentDomain.GetAssemblies() )
TryRegister( assembly );
// Register for any assemblies loaded in the future
AppDomain.CurrentDomain.AssemblyLoad += ( _, args ) => TryRegister( args.LoadedAssembly );
}
private static void TryRegister( Assembly assembly )
{
if ( assembly.IsDynamic )
return;
// SetDllImportResolver throws if called twice for the same assembly
if ( !registeredAssemblies.Add( assembly.FullName ) )
return;
NativeLibrary.SetDllImportResolver( assembly, ResolveFromNativePath );
}
private static IntPtr ResolveFromNativePath( string libraryName, Assembly assembly, DllImportSearchPath? searchPath )
{
// Specifically for fucking steam_api without using a preprocessor if statement on Platform.cs
// should try to aim to have one set of "managed" binaries without platform specific variants
if ( libraryName == "steam_api64" && !OperatingSystem.IsWindows() )
{
libraryName = "libsteam_api";
}
var nativeName = true switch
{
_ when OperatingSystem.IsWindows() => $"{libraryName}.dll",
_ when OperatingSystem.IsMacOS() => $"{libraryName}.dylib",
_ when OperatingSystem.IsLinux() => $"{libraryName}.so",
_ => libraryName
};
if ( NativeLibrary.TryLoad( Path.Combine( NetCore.NativeDllPath, nativeName ), out var handle ) )
{
return handle;
}
return IntPtr.Zero;
}
}