예제 #1
0
        ///// <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();
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        /// <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);
            }
        }