/** * @file nstdc_dl.c * @brief 動的リンクライブラリを扱う. * @author Nomura Kei * @copyright 2003 - 2017 Nomura Kei * License: New BSD License (3-cclause BSD license) */ #include <nstdc_dlfcn.h> #if (nstdc_is_windows()) #include <nstdc_errno.h> #else #include <dlfcn.h> #endif /* ----------------------------------------------------------------------------- * 内部変数 * ----------------------------------------------------------------------------- */ #if (nstdc_is_windows()) #define MAX_DL_MSGBUF (256) static int nstdc_dl_last_errno = 0; static char nstdc_dl_errmsg[MAX_DL_MSGBUF]; #endif /** * 指定された filename のライブラリをロードします. * * @param filename ライブラリ名 * @return ライブラリのハンドル */ nstdc_dl_handle_t nstdc_dlopen(const char* filename) { nstdc_dl_handle_t handle; #if (nstdc_is_windows()) handle = LoadLibraryEx(filename, 0, LOAD_WITH_ALTERED_SEARCH_PATH); nstdc_dl_last_errno = nstdc_get_errno(); #else handle = dlopen(filename, RTLD_LAZY); #endif return handle; } /** * nstdc_dlopen, nstdc_dlsym, nstdc_dlclose のいずれかで * 最後に発生したエラーについての説明メッセージを返します. * * @return エラーについての説明メッセージ */ char* nstdc_dlerror(void) { #if (nstdc_is_windows()) /* エラー番号よりエラーメッセージを取得して返す. */ bool ret = nstdc_get_errmsg(nstdc_dl_last_errno, nstdc_dl_errmsg, sizeof(nstdc_dl_errmsg)); if (!ret) { nstdc_dl_errmsg[0] = '\0'; } return nstdc_dl_errmsg; #else return dlerror(); #endif } /** * 指定されたシンボル(関数名)のポインタを返します. * * @param handle ライブラリのハンドル * @param symbol シンボル * @return シンボルのアドレス */ nstdc_dl_func_t nstdc_dlsym(nstdc_dl_handle_t handle, const char* symbol) { nstdc_dl_func_t func; #if (nstdc_is_windows()) func = GetProcAddress(handle, symbol); nstdc_dl_last_errno = nstdc_get_errno(); #else func = dlsym(handle, symbol); #endif return func; } /** * 指定されたロード済みライブラリの参照カウントを1減らします. * 参照カウントが0になり, 他でロードされているライブラリによって * シンボルが使われていなければ, そのダイナミックライブラリは * アンロードされます. * * @param handle ライブラリのハンドル */ bool nstdc_dlclose(nstdc_dl_handle_t handle) { bool result; #if (nstdc_is_windows()) BOOL ret = FreeLibrary(handle); nstdc_dl_last_errno = nstdc_get_errno(); result = (ret != 0); #else int ret = dlclose(handle); result = (ret == 0); #endif return result; }