Rhino 8 & .net 7 - loading native DLL's

I found a workaround - one solution is to use a NativeLibrary.SetDllImportResolver see documentation here.
This allows you to prompt the .net runtime with the path of the dll’s on disk.
The tricky part is that these resolvers have to be added to each assembly (dll) in your project which needs to resolve the dll. In our case I had to add a resolver to one of our dependencies also.
Maybe there is a more elegant or global solution to add the path.

Anyway I leave my code below in case anyone runs into this.
It is specific to loading OpenCVSharp but should be easy enough to modify

using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;

namespace Dalmatian;

public static class OpenCVResolver {
	private static string _assemblyLocation = string.Empty;
	private const  string RuntimeFolder64  = @"\runtimes\win-x64\native\";
	private const  string RuntimeFolder86  = @"\runtimes\win-x86\native\";

	public static void Start() {
		// first find out where our plugin lives on disk
		var executingAssembly = Assembly.GetExecutingAssembly();
		_assemblyLocation = Path.GetDirectoryName(executingAssembly.Location);
		// then add a resolver to both our plugin dll and to OpenCVSharp.dll 
		NativeLibrary.SetDllImportResolver(executingAssembly, Resolver);
		var opencv = Assembly.GetAssembly(typeof(OpenCvSharp.Cv2));
		if (opencv != null) {
			NativeLibrary.SetDllImportResolver(opencv, Resolver);
		}
	}

	private static IntPtr Resolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath) {
		if (libraryName.Contains("opencv", StringComparison.InvariantCultureIgnoreCase)) {
			var proposedPath = _assemblyLocation
			                 + (Environment.Is64BitProcess ? RuntimeFolder64 : RuntimeFolder86)
			                 + libraryName + ".dll";
			if (File.Exists(proposedPath)) {
				return NativeLibrary.Load(proposedPath, assembly, searchPath);
			}

		}
		return IntPtr.Zero;
	}
}
1 Like