📄 cl_library.cpp
字号:
/*
**
** ClanLib Game SDK
** Copyright (C) 2003 The ClanLib Team
** For a total list of contributers see the file CREDITS.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library 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
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
**
*/
#include "Core/precomp.h"
#include "API/Core/System/cl_library.h"
#ifdef USE_DYN
#include <dlfcn.h>
#endif
#include <iostream>
std::map<std::string, CL_LibraryFactoryMaker *, std::less<std::string> > CL_LibraryManager::libraries;
CL_LibraryLoader::CL_LibraryLoader(const std::string& file) : filename(file), loaded(false), handle(0), last_error(0)
{
// Be sure to end the given filename with the right extension
if(filename.rfind(".so",filename.size()) == std::string::npos)
{
filename.append(".so");
}
}
CL_LibraryLoader::~CL_LibraryLoader()
{
// Don't forget to unload the library if needed
if((loaded == true) && (handle != 0))
unload();
}
std::string CL_LibraryLoader::name() const
{
return filename;
}
bool CL_LibraryLoader::is_loaded() const
{
return loaded;
}
void *CL_LibraryLoader::resolve(const std::string& symbol)
{
#ifdef USE_DYN
// Just in case the handle has been corrupted
if(handle == 0)
return 0;
// Lookup the symbol name
void *adr = dlsym(handle,symbol.c_str());
const char *error = dlerror();
// If the error is not NULL, then the dlsym call failed
if(error != 0)
{
if(last_error != 0)
delete last_error;
last_error = new CL_Error(std::string(error));
return 0;
}
#else
void *adr = 0;
if(last_error != 0)
delete last_error;
last_error = new CL_Error(std::string("ClanLib hasn't been built with dynamic loading support"));
#endif
return adr;
}
bool CL_LibraryLoader::load()
{
#ifdef USE_DYN
// We use RTLD_LAZY|RTLD_GLOBAL which is a good default nowadays
handle = dlopen(filename.c_str(), RTLD_LAZY|RTLD_GLOBAL);
if(handle == 0)
{
const char *error = dlerror();
// If the error is not NULL, then the dlopen call failed
if(error != 0)
{
if(last_error != 0)
delete last_error;
last_error = new CL_Error(std::string(error));
}
loaded = false;
}
else
{
loaded = true;
}
#else
loaded = false;
if(last_error != 0)
delete last_error;
last_error = new CL_Error(std::string("ClanLib hasn't been built with dynamic loading support"));
#endif
return loaded;
}
bool CL_LibraryLoader::unload()
{
#ifdef USE_DYN
if(last_error != 0)
{
delete last_error;
last_error = 0;
}
// Well if the handle is already NULL, don't need to unload it again
if(handle == 0)
return true;
if(dlclose(handle) != 0)
{
last_error = new CL_Error(std::string(dlerror()));
return false;
}
handle = 0;
loaded = false;
#endif
return true;
}
CL_Error *CL_LibraryLoader::get_last_error() const
{
if(last_error == 0)
return new CL_Error(std::string("No CL_Library error set so far"));
return last_error;
}
CL_LibraryFactoryMaker_t CL_LibraryManager::get(const std::string& lib_name)
{
std::map<std::string, CL_LibraryFactoryMaker *, std::less<std::string> >::iterator libs_itr;
CL_LibraryFactoryMaker_t lib;
bool found = true;
if((libs_itr = libraries.find(lib_name)) != libraries.end())
{
lib = (*libs_itr).second;
}
else
{
found = false;
}
if(found == false)
return 0;
return lib;
}
void CL_LibraryManager::add(const std::string& lib_name,CL_LibraryFactoryMaker *lib)
{
libraries[lib_name] = lib;
}
void CL_LibraryManager::remove(const std::string& lib_name)
{
if(libraries.find(lib_name) != libraries.end())
libraries.erase(lib_name);
}
bool CL_LibraryManager::has(const std::string& lib_name)
{
if(libraries.find(lib_name) != libraries.end())
return true;
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -