///// <summary> ///// destructor - calls dispose ///// </summary> //~DynLibLoader() { // this.Dispose(); //} #region IDisposable Members /// <summary> /// unloads the library /// </summary> virtual public void Dispose() { if (m_LibHandle.val != IntPtr.Zero) { DynamicLibraries.UnloadDynLib(m_LibHandle); m_LibHandle.val = IntPtr.Zero; UnloadAllDelegates(); } }
private bool LoadAllDelegates(GetNameMangling NameMangling, string LibName) { Type myType = this.GetType(); FieldInfo[] fields = myType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); m_LoadedSymbols.Clear(); Delegate2FunctionPointer.Clear(); // loop over all delegates .... bool success = true; foreach (FieldInfo fld in fields) { if (IsDelegate(fld.FieldType)) { m_LoadedSymbols.Add(fld); // get function name in DLL string UnmanagedName = NameMangling(fld.Name); Info("Trying to load '" + fld.Name + "' as '" + UnmanagedName + "' ..."); // get function pointer string errstr2; IntPtr FuncPtr = DynamicLibraries.LoadSymbol(m_LibHandle, UnmanagedName, out errstr2); if (FuncPtr == IntPtr.Zero) { //throw new ApplicationException("Library '" + LibNames[i] + "' not working - missing function '" + UnmanagedName + "';"); // try next library .. DynamicLibraries.UnloadDynLib(m_LibHandle); m_LibHandle.val = IntPtr.Zero; success = false; Info("FAILED: >" + errstr2 + "<"); break; } else { Info("SUCCESS."); } // create delegate Delegate del = Marshal.GetDelegateForFunctionPointer(FuncPtr, fld.FieldType); if (del == null) { Warn("unable to get delegate from function pointer: library '" + LibName + "', symbol '" + UnmanagedName + "';"); throw new ApplicationException("unable to get delegate from function pointer: library '" + LibName + "', symbol '" + UnmanagedName + "';"); } fld.SetValue(this, del); Delegate2FunctionPointer.Add(del, FuncPtr); } } return(success); }
/// <summary> /// ctor /// </summary> /// <param name="_LibNames"> /// a list of library names; e.g. different names of the library on various systems, /// or alternative implementations (e.g. various BLAS - implementations) on the same system /// </param> /// <param name="OsFilter"> /// Operating system filter /// </param> /// <param name="NameMangling"> /// name mangling, suggestions are: <see cref="LeadingUnderscore_SmallLetters"/>, <see cref="SmallLetters_TrailingUnderscore"/> /// or <see cref="CAPITAL_LETTERS"/> /// </param> /// <param name="PointerSizeFilter"> /// library is excluded from search if the size of pointers (usually 4 or 8 bytes) in not equal; /// This is for libs which require a different name mangling in 64 and 32 bit mode; /// Ignored, when negative; /// </param> /// <param name="PrequesiteLibraries"> /// 1st index: correlates with library names /// 2nd index: chain of required prequesites /// 3rd index: for each required prequesite, a list of alternatives. /// </param> protected DynLibLoader(string[] _LibNames, string[][][] PrequesiteLibraries, GetNameMangling[] NameMangling, PlatformID[] OsFilter, int[] PointerSizeFilter) { m_debugoutput = new StringWriter(); if (_LibNames.Length != OsFilter.Length || OsFilter.Length != NameMangling.Length || PointerSizeFilter.Length != NameMangling.Length || _LibNames.Length != PrequesiteLibraries.Length) { throw new ApplicationException("all arrays must have the same length."); } PlatformID CurrentSys = System.Environment.OSVersion.Platform; // MacOS tweak if (CurrentSys == PlatformID.Unix && IsRunningOnMac()) { CurrentSys = PlatformID.MacOSX; } List <DirectoryInfo> LibrarySearchPath = GetLibrarySearchDirs(CurrentSys); Info("Pointer size: " + IntPtr.Size); for (int k = 0; k < _LibNames.Length; k++) { // apply OS and byteness-filters // ============================= { Info("Trying with '" + _LibNames[k] + "' ... "); if (CurrentSys != OsFilter[k]) { Info("WRONG OS"); continue; // don't search for the library 'LibNames[i]' on this system } if (PointerSizeFilter[k] >= 0 && PointerSizeFilter[k] != IntPtr.Size) { Info("MISMATCH IN POINTER BYTENESS"); continue; // don't search for the library 'LibNames[i]' on this system } Info("FILERS PASSED"); } // load prequesite library // ======================= bool PreqSuccess = true; if (PrequesiteLibraries[k] != null) { Info("prerequisite libraries required; trying to load these..."); string[][] PreqChain = PrequesiteLibraries[k]; this.m_PreqLibHandle = new DynamicLibraries.DynLibHandle[PreqChain.Length]; int cnt = 0; foreach (string[] PreqAlt in PreqChain) { foreach (var LibName in GetLibraryFiles(PreqAlt, LibrarySearchPath)) { Info("trying to load '" + LibName + "' (prerequisite) ... "); string errstr; m_PreqLibHandle[cnt] = DynamicLibraries.LoadDynLib(LibName, out errstr, true); if (m_PreqLibHandle[cnt].val == IntPtr.Zero) { Info("FAILED: >" + errstr + "<"); } else { Info("SUCCESS. going on to next prerequisite."); break; } } if (m_PreqLibHandle[cnt].val == IntPtr.Zero) { Info("FAILED on loading any of the prerequisite libraries " + CatStrings(PreqAlt) + "."); for (int i = 0; i < cnt; i++) { DynamicLibraries.UnloadDynLib(m_PreqLibHandle[i]); } PreqSuccess = false; break; } cnt++; } } else { this.m_PreqLibHandle = new DynamicLibraries.DynLibHandle[0]; } if (!PreqSuccess) { Info("UNABLE TO LOAD MAIN LIBRARY. Failed on some of the prerequesites."); continue; } // load the main library // ===================== bool mainLibsuccess = false; foreach (var LibName in GetLibraryFiles(_LibNames[k], LibrarySearchPath)) { Info("trying to load '" + LibName + "' ... "); string errstr; m_LibHandle = DynamicLibraries.LoadDynLib(LibName, out errstr, false); if (m_LibHandle.val == IntPtr.Zero) { Info("FAILED: >" + errstr + "<"); continue; } else { Info("SUCCESS."); } bool success = LoadAllDelegates(NameMangling[k], LibName); if (success) { // successfully loaded all library functions //Console.WriteLine("success in : " + LibNames[i]); //Console.WriteLine("success."); CurrentLibraryName = LibName; mainLibsuccess = true; break; } else { UnloadAllDelegates(); } } if (mainLibsuccess) { return; } } // error { StringWriter stw = new StringWriter(); int cnt = 1; foreach (string s in _LibNames) { stw.Write(s); if (cnt < _LibNames.Length) { stw.Write(", "); } cnt++; } throw new ApplicationException("unable to find/load dynamic library " + stw.ToString() + " on current system." + "Extended info:" + System.Environment.NewLine + "------------------------------------------------------------------------" + System.Environment.NewLine + m_debugoutput.ToString() + "------------------------------------------------------------------------" + System.Environment.NewLine); } }