/// <summary>
        /// Loads a native library with a reflected assembly holding the native libraries
        /// </summary>
        /// <param name="assembly">The assembly to load from</param>
        /// <param name="localLoadOnRio">True to force a local load on the RoboRIO</param>
        public void LoadNativeLibraryFromAssembly(Assembly assembly, bool localLoadOnRio = true)
        {
            if (localLoadOnRio && CheckIsRoboRio())
            {
                ILibraryLoader loader = new EmbeddedLibraryLoader();
                LibraryLoader = loader;
                var location = m_nativeLibraryName[OsType.roboRIO];
                loader.LoadLibrary(location);
                LibraryLocation = location;
                return;
            }

            if (OsType == OsType.None)
            {
                throw new InvalidOperationException(
                          "OS type is unknown. Must use the overload to manually load the file");
            }

            if (!m_nativeLibraryName.ContainsKey(OsType))
            {
                throw new InvalidOperationException("OS Type not contained in dictionary");
            }

            switch (OsType)
            {
            case OsType.Windows32:
            case OsType.Windows64:
                LibraryLoader = new WindowsLibraryLoader();
                break;

            case OsType.Linux32:
            case OsType.Linux64:
                LibraryLoader = new LinuxLibraryLoader();
                break;

            case OsType.MacOs32:
            case OsType.MacOs64:
                LibraryLoader = new MacOsLibraryLoader();
                break;

            case OsType.LinuxAarch64:
            case OsType.LinuxRaspbian:
            case OsType.roboRIO:
                LibraryLoader = new EmbeddedLibraryLoader();
                break;
            }

            if (LibraryLoader == null)
            {
                throw new ArgumentNullException(nameof(LibraryLoader), "Library loader cannot be null");
            }

            string extractLocation = Path.GetTempFileName();

            UsingTempFile = true;

            ExtractNativeLibrary(m_nativeLibraryName[OsType], extractLocation, assembly);
            LibraryLoader.LoadLibrary(extractLocation);
            LibraryLocation = extractLocation;
        }
        /// <summary>
        /// Try to load a native library directly from a path
        /// </summary>
        /// <param name="libraryName"></param>
        /// <returns></returns>
        public bool TryLoadNativeLibraryPath(string libraryName)
        {
            OsType osType = OsType;

            if (osType == OsType.None)
            {
                throw new InvalidOperationException(
                          "OS type is unknown. Must use the overload to manually load the file");
            }

            ILibraryLoader loader;

            switch (osType)
            {
            case OsType.Windows32:
            case OsType.Windows64:
                loader      = new WindowsLibraryLoader();
                libraryName = $"{libraryName}.dll";
                break;

            case OsType.Linux32:
            case OsType.Linux64:
                loader      = new LinuxLibraryLoader();
                libraryName = $"lib{libraryName}.so";
                break;

            case OsType.MacOs32:
            case OsType.MacOs64:
                loader      = new MacOsLibraryLoader();
                libraryName = $"lib{libraryName}.dylib";
                break;

            case OsType.LinuxAarch64:
            case OsType.LinuxRaspbian:
            case OsType.roboRIO:
                loader      = new EmbeddedLibraryLoader();
                libraryName = $"lib{libraryName}.so";
                break;

            default:
                throw new InvalidOperationException("Unknown OS type?");
            }

            bool wasLoaded = loader.TryLoadLibrary(libraryName);

            if (wasLoaded)
            {
                LibraryLoader   = loader;
                LibraryLocation = libraryName;
            }
            return(wasLoaded);
        }
        /// <summary>
        /// Loads a native library using the specified file. The OS is determined automatically
        /// </summary>
        /// <typeparam name="T">The type containing the native resource, if it is embedded.</typeparam>
        /// <param name="location">The file location. Can be either an embedded resource, or a direct file location</param>
        /// <param name="directLoad">True to load the file directly from disk, otherwise false to extract from embedded</param>
        /// <param name="extractLocation">The location to extract to if the file is embedded. On null, it extracts to a temp file</param>
        public void LoadNativeLibrary <T>(string location, bool directLoad = false, string?extractLocation = null)
        {
            if (location == null)
            {
                throw new ArgumentNullException(nameof(location), "Library location cannot be null");
            }

            OsType osType = OsType;

            if (osType == OsType.None)
            {
                throw new InvalidOperationException(
                          "OS type is unknown. Must use the overload to manually load the file");
            }

            if (!m_nativeLibraryName.ContainsKey(osType) && !directLoad)
            {
                throw new InvalidOperationException("OS Type not contained in dictionary");
            }

            switch (osType)
            {
            case OsType.Windows32:
            case OsType.Windows64:
                LibraryLoader = new WindowsLibraryLoader();
                break;

            case OsType.Linux32:
            case OsType.Linux64:
                LibraryLoader = new LinuxLibraryLoader();
                break;

            case OsType.MacOs32:
            case OsType.MacOs64:
                LibraryLoader = new MacOsLibraryLoader();
                break;

            case OsType.LinuxAarch64:
            case OsType.LinuxRaspbian:
            case OsType.roboRIO:
                LibraryLoader = new EmbeddedLibraryLoader();
                break;
            }

            LoadNativeLibrary <T>(LibraryLoader, location, directLoad, extractLocation);
        }