Browse Source

Changed to use LoadLibraryEx rather than LoadLibrary to properly find library dependencies and added searching for the architecture specific folder in the current domain's base directory which fixes a problem with running unit tests with MSTest / Xunit in Visual Studio (assemblies seem to be copied to the temp directory so fails to find the native library).

cuda
Kuan Bartel 12 years ago
parent
commit
67642e9c76
  1. 23
      src/Numerics/Providers/NativeProviderLoader.cs

23
src/Numerics/Providers/NativeProviderLoader.cs

@ -115,6 +115,7 @@ namespace MathNet.Numerics.Providers
public static Exception LastException { get; private set; }
private static object staticLock = new Object();
/// <summary>
/// Load the native library with the given filename.
/// </summary>
@ -125,15 +126,21 @@ namespace MathNet.Numerics.Providers
if (string.IsNullOrEmpty(fileName))
throw new ArgumentNullException("fileName");
lock(staticLock)
lock (staticLock)
{
IntPtr libraryHandle = IntPtr.Zero;
if (NativeHandles.TryGetValue(fileName, out libraryHandle))
return true;
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), ArchDirectory, fileName);
if (string.IsNullOrEmpty(ArchDirectory))
return false;
// Look for the library in a acrhtecture directory under the current AppDomain's base directory or this assembly's directory
string path = Path.Combine(Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory), ArchDirectory, fileName);
if (!File.Exists(path))
path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), ArchDirectory, fileName);
if (string.IsNullOrEmpty(ArchDirectory) || !File.Exists(path))
if (!File.Exists(path))
{
// If the library isn't found within an architecture specific folder then return false
// to allow normal P/Invoke searching behaviour when the library is called
@ -162,8 +169,16 @@ namespace MathNet.Numerics.Providers
[SecurityCritical]
private static class WindowsLoader
{
public static IntPtr LoadLibrary(string fileName)
{
return LoadLibraryEx(fileName, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH);
}
// Search for dependencies in the library's directory rather than the calling process's directory
const uint LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;
[DllImport("kernel32", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr LoadLibrary(string fileName);
private static extern IntPtr LoadLibraryEx(string fileName, IntPtr reservedNull, uint flags);
}
[SuppressUnmanagedCodeSecurity]

Loading…
Cancel
Save