/* Copyright (C) 2014 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * 0 A.D. is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 0 A.D. If not, see . */ #ifndef INCLUDED_DLLLOADER #define INCLUDED_DLLLOADER #include "ps/Errors.h" #include "ps/CLogger.h" ERROR_GROUP(DllLoader); ERROR_TYPE(DllLoader, DllNotLoaded); ERROR_TYPE(DllLoader, SymbolNotFound); class DllLoader { public: /** * Prepare the DLL loader. Does no actual work. * * @param name base name of the library (from which we'll derive * "name.dll", "libname_dbg.so", etc). Pointer must remain valid for * this object's lifetime (which is fine if you just use a string literal). * @param loadErrorLogMethod Allows to set the CLogger log level that is * used when the DllLoader reports loading errors. */ DllLoader(const char* name, CLogger::ELogMethod loadErrorLogMethod = CLogger::Error); ~DllLoader(); /** * Attempt to load and initialise the library, if not already. Can be harmlessly * called multiple times. Returns false if unsuccessful. */ bool LoadDLL(); /** * Check whether the library has been loaded successfully. Returns false * before {@link #LoadDLL} has been called; otherwise returns the same as * LoadDLL did. */ bool IsLoaded() const; /** * Unload the library, if it has been loaded already. (Usually not needed, * since the destructor will unload it.) */ void Unload(); /** * Attempt to load a named symbol from the library. If {@link #IsLoaded} is * false, throws PSERROR_DllLoader_DllNotLoaded. If it cannot load the * symbol, throws PSERROR_DllLoader_SymbolNotFound. In both cases, sets fptr * to NULL. Otherwise, fptr is set to point to the loaded function. * * @throws PSERROR_DllLoader */ template void LoadSymbol(const char* name, T& fptr) const; /** * Override the build-time setting of the directory to search for libraries. */ static void OverrideLibdir(const char* libdir); private: // Typeless version - the public LoadSymbol hides the slightly ugly // casting from users. void LoadSymbolInternal(const char* name, void** fptr) const; void LogLoadError(const char* errors); const char* m_Name; void* m_Handle; CLogger::ELogMethod m_LoadErrorLogMethod; }; template void DllLoader::LoadSymbol(const char* name, T& fptr) const { LoadSymbolInternal(name, (void**)&fptr); } #endif // INCLUDED_DLLLOADER