From c7b53b7f1f22a27ac9a39cf8c4ebc8288eb59fe2 Mon Sep 17 00:00:00 2001 From: AnthonyKwon Date: Thu, 19 Mar 2026 05:47:17 +0900 Subject: [PATCH 1/3] proper ARM64 detection for macOS --- src/LibVLCSharp/Shared/Core/Constants.cs | 1 + src/LibVLCSharp/Shared/Core/Core.cs | 24 +++++++++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/LibVLCSharp/Shared/Core/Constants.cs b/src/LibVLCSharp/Shared/Core/Constants.cs index e36b8e45..a80cb875 100644 --- a/src/LibVLCSharp/Shared/Core/Constants.cs +++ b/src/LibVLCSharp/Shared/Core/Constants.cs @@ -35,6 +35,7 @@ internal static class ArchitectureNames internal const string Win64 = "win-x64"; internal const string Win86 = "win-x86"; internal const string MacOS64 = "osx-x64"; + internal const string MacOSArm64 = "osx-arm64"; } [Flags] diff --git a/src/LibVLCSharp/Shared/Core/Core.cs b/src/LibVLCSharp/Shared/Core/Core.cs index 2afe6598..4e80658c 100644 --- a/src/LibVLCSharp/Shared/Core/Core.cs +++ b/src/LibVLCSharp/Shared/Core/Core.cs @@ -73,12 +73,16 @@ static internal bool LibVLCLoaded var paths = new List<(string, string)>(); string arch; +#if !NET40 && !NETSTANDARD1_1 if (PlatformHelper.IsMac) { - arch = Path.Combine(ArchitectureNames.MacOS64, Constants.Lib); + arch = RuntimeInformation.ProcessArchitecture switch + { + Architecture.X64 => Path.Combine(ArchitectureNames.MacOS64, Constants.Lib), + Architecture.Arm64 => Path.Combine(ArchitectureNames.MacOSArm64, Constants.Lib), + _ => Path.Combine(ArchitectureNames.MacOS64, Constants.Lib), + }; } - -#if !NET40 && !NETSTANDARD1_1 else if (PlatformHelper.IsWindows) { arch = RuntimeInformation.ProcessArchitecture switch @@ -89,9 +93,8 @@ static internal bool LibVLCLoaded _ => PlatformHelper.IsX64BitProcess ? ArchitectureNames.Win64 : ArchitectureNames.Win86 }; } -#endif - else +#endif { arch = PlatformHelper.IsX64BitProcess ? ArchitectureNames.Win64 : ArchitectureNames.Win86; } @@ -138,11 +141,14 @@ static internal bool LibVLCLoaded paths.Add((string.Empty, libvlcPath3)); - // Add Win64 folders as fallback for WinArm64 to keep compatibility - if (arch == ArchitectureNames.WinArm64) + // Add x64 folders as fallback for ARM64 to keep compatibility + if (arch == ArchitectureNames.WinArm64 || arch == Path.Combine(ArchitectureNames.MacOSArm64, Constants.Lib)) { + var fallbackArchitecture = arch == ArchitectureNames.WinArm64 + ? ArchitectureNames.Win64 : ArchitectureNames.MacOS64; + var fallbackLibvlcDirPath1 = Path.Combine(Path.GetDirectoryName(libvlcAssemblyLocation)!, - Constants.LibrariesRepositoryFolderName, ArchitectureNames.Win64); + Constants.LibrariesRepositoryFolderName, fallbackArchitecture); var fallbackLibvlccorePath1 = LibVLCCorePath(fallbackLibvlcDirPath1); var fallbackLibvlcPath1 = LibVLCPath(fallbackLibvlcDirPath1); @@ -151,7 +157,7 @@ static internal bool LibVLCLoaded if (!string.IsNullOrEmpty(assemblyLocation)) { var fallbackLibvlcDirPath2 = Path.Combine(Path.GetDirectoryName(assemblyLocation)!, - Constants.LibrariesRepositoryFolderName, ArchitectureNames.Win64); + Constants.LibrariesRepositoryFolderName, fallbackArchitecture); var fallbackLibvlccorePath2 = LibVLCCorePath(fallbackLibvlcDirPath2); var fallbackLibvlcPath2 = LibVLCPath(fallbackLibvlcDirPath2); From 126a0113394788460ff9629ab94647e4a9f71637 Mon Sep 17 00:00:00 2001 From: AnthonyKwon Date: Wed, 5 Aug 2026 15:01:58 +0900 Subject: [PATCH 2/3] Register custom resolver to load library from corrected path --- src/LibVLCSharp/Shared/Core/Core.cs | 30 +++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/LibVLCSharp/Shared/Core/Core.cs b/src/LibVLCSharp/Shared/Core/Core.cs index 4e80658c..7ba7fde3 100644 --- a/src/LibVLCSharp/Shared/Core/Core.cs +++ b/src/LibVLCSharp/Shared/Core/Core.cs @@ -194,6 +194,19 @@ static void LoadLibVLC(string? libvlcDirectoryPath = null) loadResult = LoadNativeLibrary(libvlcPath, out LibvlcHandle); if (!loadResult) Log($"Failed to load required native libraries at {libvlcPath}"); + +#if NET5_0_OR_GREATER + // register custom resolver to load library from provided path + NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), (dll, _, _) => + { + return dll switch + { + Constants.LibraryName => NativeLibrary.Load(libvlcPath), + Constants.CoreLibraryName => NativeLibrary.Load(libvlccorePath), + _ => IntPtr.Zero + }; + }); +#endif return; } @@ -203,8 +216,21 @@ static void LoadLibVLC(string? libvlcDirectoryPath = null) { LoadNativeLibrary(libvlccore, out LibvlccoreHandle); var loadResult = LoadNativeLibrary(libvlc, out LibvlcHandle); - if (loadResult) - break; + if (!loadResult) continue; + +#if NET5_0_OR_GREATER + // register custom resolver to load library from discovered path + NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), (dll, _, _) => + { + return dll switch + { + Constants.LibraryName => NativeLibrary.Load(libvlc), + Constants.CoreLibraryName => NativeLibrary.Load(libvlccore), + _ => IntPtr.Zero + }; + }); +#endif + break; } if (!LibVLCLoaded) From 6fce46a68ed811b5653edac6157b86a4b0088a72 Mon Sep 17 00:00:00 2001 From: AnthonyKwon Date: Thu, 6 Aug 2026 04:22:44 +0900 Subject: [PATCH 3/3] Remove appending lib from macOS path --- src/LibVLCSharp/Shared/Core/Core.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/LibVLCSharp/Shared/Core/Core.cs b/src/LibVLCSharp/Shared/Core/Core.cs index 7ba7fde3..bb5fbeb7 100644 --- a/src/LibVLCSharp/Shared/Core/Core.cs +++ b/src/LibVLCSharp/Shared/Core/Core.cs @@ -78,9 +78,8 @@ static internal bool LibVLCLoaded { arch = RuntimeInformation.ProcessArchitecture switch { - Architecture.X64 => Path.Combine(ArchitectureNames.MacOS64, Constants.Lib), - Architecture.Arm64 => Path.Combine(ArchitectureNames.MacOSArm64, Constants.Lib), - _ => Path.Combine(ArchitectureNames.MacOS64, Constants.Lib), + Architecture.Arm64 => ArchitectureNames.MacOSArm64, + _ => ArchitectureNames.MacOS64, }; } else if (PlatformHelper.IsWindows) @@ -142,7 +141,7 @@ static internal bool LibVLCLoaded paths.Add((string.Empty, libvlcPath3)); // Add x64 folders as fallback for ARM64 to keep compatibility - if (arch == ArchitectureNames.WinArm64 || arch == Path.Combine(ArchitectureNames.MacOSArm64, Constants.Lib)) + if (arch == ArchitectureNames.WinArm64 || arch == ArchitectureNames.MacOSArm64) { var fallbackArchitecture = arch == ArchitectureNames.WinArm64 ? ArchitectureNames.Win64 : ArchitectureNames.MacOS64; @@ -167,9 +166,8 @@ static internal bool LibVLCLoaded if (PlatformHelper.IsMac) { - var libvlcPath4 = Path.Combine(Path.Combine(Path.GetDirectoryName(libvlcAssemblyLocation)!, - Constants.Lib), $"{Constants.LibVLC}{LibraryExtension}"); - var libvlccorePath4 = LibVLCCorePath(Path.Combine(Path.GetDirectoryName(libvlcAssemblyLocation)!, Constants.Lib)); + var libvlcPath4 = Path.Combine(Path.GetDirectoryName(libvlcAssemblyLocation)!, $"{Constants.LibVLC}{LibraryExtension}"); + var libvlccorePath4 = LibVLCCorePath(Path.GetDirectoryName(libvlcAssemblyLocation)!); paths.Add((libvlccorePath4, libvlcPath4)); }