//////////////////////////////////////////////////////////////////////////////// // // ライブラリの動的ロードを行うモジュール // #include <kcpp_dl.hpp> #if (!KCPP_IS_WINDOWS) #include <dlfcn.h> #endif namespace kcpp { //////////////////////////////////////////////////////////////////////////// // // DynamicLoadException // /** * 最後に発生したエラーメッセージを持つ Exception を構築します。 * エラーメッセージを取得できない場合、空文字がメッセージに設定されます。 */ DynamicLoadException::DynamicLoadException() noexcept : Exception() { // NOP } /** * コピーコンストラクタ。 * * @param t コピー元 */ DynamicLoadException::DynamicLoadException(const DynamicLoadException& t) noexcept : Exception(t) { // NOP } /** * 指定されたメッセージを持つ Exception を構築します。 * * @param msg メッセージ */ DynamicLoadException::DynamicLoadException(const std::string& msg) noexcept : Exception(msg) { // NOP } /** * デストラクタ。 */ DynamicLoadException::~DynamicLoadException() noexcept { // NOP } //////////////////////////////////////////////////////////////////////////// // // DynamicLoader // /** * 指定された動的ライブラリをロードします。 * ロードに失敗した場合、DynamicLoadException を throw します。 * * @param name ロードする動的ライブラリ */ DynamicLoader::DynamicLoader(const std::string& name) : handle(nullptr) { #if (KCPP_IS_WINDOWS) handle = ::LoadLibraryEx(name.c_str(), 0, LOAD_WITH_ALTERED_SEARCH_PATH); #else handle = ::dlopen(name.c_str(), RTLD_LAZY); #endif if (handle == nullptr) { throw DynamicLoadException("can't load file"); } } /** * 指定された動的ライブラリをアンロードします。 */ DynamicLoader::~DynamicLoader() { #if (KCPP_IS_WINDOWS) ::FreeLibrary(handle); #else ::dlclose(handle); #endif } /** * 指定されたシンボルがロードされたアドレスを返します。 * 該当シンボルが見つからない場合、DynamicLoadException を throw します。 * * @param name シンボル名 */ dl_func_t DynamicLoader::sym(const std::string& name) { dl_func_t func; #if (KCPP_IS_WINDOWS) func = ::GetProcAddress(handle, name.c_str()); if (func == nullptr) { throw DynamicLoadException("no such symbol"); } #else (void) dlerror(); func = ::dlsym(handle, name.c_str()); char* errmsg = dlerror(); if (errmsg != nullptr) { throw DynamicLoadException(errmsg); } #endif return func; } }