If you want to load the right library according bitness of your AnyCPU program, do the following:
- get
RuntimeInformation.ProcessArchitecture
for your program
- load the right one from the two versions you have
The loader:
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.InteropServices;
using JetBrains.Annotations;
namespace Aubio.NET.Win32.Unused
{
/// <summary>
/// Helper for loading a native library.
/// </summary>
[PublicAPI]
public class NativeLibraryLoader : IDisposable
{
/// <summary>
/// Initializes a new instance of the <see cref="NativeLibraryLoader" /> class.
/// </summary>
/// <param name="path32">
/// Path to the 32-bit binary of the library.
/// </param>
/// <param name="path64">
/// Path to the 64-bit binary of the library.
/// </param>
/// <exception cref="FileNotFoundException">
/// <paramref name="path64" /> or <paramref name="path64" /> were not found.
/// </exception>
/// <exception cref="PlatformNotSupportedException">
/// The library could not be loaded.
/// </exception>
/// <exception cref="FileNotFoundException">
/// The platform is not supported.
/// </exception>
[SuppressMessage("ReSharper", "SwitchStatementMissingSomeCases")]
public NativeLibraryLoader(string path32, string path64)
{
if (!File.Exists(path32))
throw new FileNotFoundException("32-bit library not found.", path32);
if (!File.Exists(path64))
throw new FileNotFoundException("64-bit library not found.", path64);
string path;
switch (RuntimeInformation.ProcessArchitecture)
{
case Architecture.X86:
path = path32;
break;
case Architecture.X64:
path = path64;
break;
default:
throw new PlatformNotSupportedException();
}
NativeLibraryHandle handle;
var description = RuntimeInformation.FrameworkDescription;
if (description.StartsWith(".NET Framework"))
handle = NativeMethods.LoadLibrary(path);
else if (description.StartsWith(".NET Core"))
handle = NativeMethods.LoadPackagedLibrary(path);
else
throw new PlatformNotSupportedException();
if (handle.IsInvalid)
throw new InvalidOperationException("Library could not be loaded.", new Win32Exception());
Handle = handle;
}
[NotNull]
private NativeLibraryHandle Handle { get; }
/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (Handle.IsInvalid == false)
Handle.Dispose();
}
/// <inheritdoc />
~NativeLibraryLoader()
{
Dispose(false);
}
}
}
The handle:
using System;
using System.Runtime.InteropServices;
using JetBrains.Annotations;
namespace Aubio.NET.Win32.Unused
{
[UsedImplicitly]
public sealed class NativeLibraryHandle : SafeHandle
{
private static readonly IntPtr InvalidHandleValue = IntPtr.Zero;
public NativeLibraryHandle() : base(InvalidHandleValue, true)
{
}
/// <inheritdoc />
public override bool IsInvalid => handle == InvalidHandleValue;
/// <inheritdoc />
protected override bool ReleaseHandle()
{
return NativeMethods.FreeLibrary(handle);
}
}
}
The native methods class:
using System;
using System.Runtime.InteropServices;
using System.Text;
using Aubio.NET.Win32.Unused;
namespace Aubio.NET.Win32
{
internal static class NativeMethods
{
/// <summary>
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx
/// </summary>
/// <param name="lpLibFileName"></param>
/// <returns></returns>
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern NativeLibraryHandle LoadLibrary(string lpLibFileName);
/// <summary>
/// https://msdn.microsoft.com/en-us/library/windows/desktop/hh447159(v=vs.85).aspx
/// </summary>
/// <param name="lpwLibFileName"></param>
/// <param name="reserved"></param>
/// <returns></returns>
[DllImport("kernel32.dll", EntryPoint = "LoadPackagedLibrary", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern NativeLibraryHandle LoadPackagedLibrary(string lpwLibFileName, uint reserved = 0);
/// <summary>
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683152(v=vs.85).aspx
/// </summary>
/// <param name="hModule"></param>
/// <returns></returns>
[DllImport("kernel32.dll", EntryPoint = "FreeLibrary", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FreeLibrary(IntPtr hModule);
/// <summary>
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx
/// </summary>
/// <param name="hModule"></param>
/// <param name="lpProcName"></param>
/// <returns></returns>
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
/// <summary>
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683186(v=vs.85).aspx
/// </summary>
/// <param name="nBufferLength"></param>
/// <param name="lpBuffer"></param>
/// <returns></returns>
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint GetDllDirectory(uint nBufferLength, [Out] StringBuilder lpBuffer);
/// <summary>
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686203(v=vs.85).aspx
/// </summary>
/// <param name="lpPathName"></param>
/// <returns></returns>
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetDllDirectory(string lpPathName);
/// <summary>
/// https://msdn.microsoft.com/en-us/library/windows/desktop/hh310513(v=vs.85).aspx
/// </summary>
/// <param name="newDirectory"></param>
/// <returns></returns>
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr AddDllDirectory(string newDirectory);
/// <summary>
/// https://msdn.microsoft.com/en-us/library/windows/desktop/hh310514(v=vs.85).aspx
/// </summary>
/// <param name="cookie"></param>
/// <returns></returns>
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool RemoveDllDirectory(IntPtr cookie);
/// <summary>
/// https://msdn.microsoft.com/en-us/library/windows/desktop/hh310515(v=vs.85).aspx
/// </summary>
/// <param name="directoryFlags"></param>
/// <returns></returns>
[DllImport("kernel32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetDefaultDllDirectories(uint directoryFlags);
}
}
Source:
https://github.com/aybe/aubio.net/tree/develop/Aubio.NET/Win32
https://github.com/aybe/aubio.net/tree/develop/Aubio.NET/Win32/Unused