25 #define WIN32_LEAN_AND_MEAN
73 if (!dst || dst_sz == 0 || !src)
82 memcpy(dst, src, n + 1);
97 const char *last = path;
101 for (p = path; *p; ++p)
103 if (*p ==
'/' || *p ==
'\\')
129 char *so_ver = strstr(s,
".so.");
137 size_t len = strlen(s);
138 if (len >= 3 && strcmp(s + (len - 3),
".so") == 0)
146 size_t len = strlen(s);
147 if (len >= 6 && strcmp(s + (len - 6),
".dylib") == 0)
156 dot = strrchr(s,
'.');
178 if (!w || !out_u8 || out_u8_sz == 0)
181 need = WideCharToMultiByte(CP_UTF8, 0, w, -1, NULL, 0, NULL, NULL);
184 if ((
size_t)need > out_u8_sz)
187 if (WideCharToMultiByte(CP_UTF8, 0, w, -1, out_u8, (
int)out_u8_sz, NULL, NULL) <= 0)
205 wchar_t buf[MAX_PATH];
208 if (!out_w || out_w_cap == 0 || !func_addr)
211 if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
212 (LPCWSTR)func_addr, &hm))
217 n = GetModuleFileNameW(hm, buf, (DWORD)(
sizeof(buf) /
sizeof(buf[0])));
218 if (n == 0 || n >= (DWORD)(
sizeof(buf) /
sizeof(buf[0])))
227 wchar_t full[MAX_PATH];
228 DWORD m = GetFullPathNameW(buf, (DWORD)(
sizeof(full) /
sizeof(full[0])), full, NULL);
229 if (m == 0 || m >= (DWORD)(
sizeof(full) /
sizeof(full[0])))
231 if (wcslen(buf) + 1 > out_w_cap)
233 wcscpy_s(out_w, out_w_cap, buf);
236 if (wcslen(full) + 1 > out_w_cap)
238 wcscpy_s(out_w, out_w_cap, full);
262 char resolved[PATH_MAX];
264 if (!out_path || out_path_sz == 0 || !func_addr)
267 memset(&info, 0,
sizeof(info));
268 if (dladdr(func_addr, &info) == 0)
273 p = info.dli_fname ? info.dli_fname :
"";
279 if (realpath(p, resolved) != NULL)
281 return copy_str(out_path, out_path_sz, resolved);
287 return copy_str(out_path, out_path_sz, p);
293 char joined[PATH_MAX];
295 if (getcwd(cwd,
sizeof(cwd)) == NULL)
297 if (snprintf(joined,
sizeof(joined),
"%s/%s", cwd, p) <= 0)
300 if (realpath(joined, resolved) != NULL)
302 return copy_str(out_path, out_path_sz, resolved);
306 return copy_str(out_path, out_path_sz, joined);
313int get_lib_path(
char *out_path,
const size_t out_path_sz,
const void *func_addr)
316 wchar_t wpath[MAX_PATH];
317 get_lib_info_status_t st = get_self_path_w(wpath, (
size_t)(
sizeof(wpath) /
sizeof(wpath[0])), func_addr);
320 if (out_path && out_path_sz)
324 return (
int)narrow_utf8(wpath, out_path, out_path_sz);
331int get_lib_basename(
char *out_basename,
const size_t out_basename_sz,
const void *func_addr)
338 if (!out_basename || out_basename_sz == 0)
341 st =
get_lib_path(path_buf,
sizeof(path_buf), func_addr);
344 out_basename[0] =
'\0';
349 if (!fname || fname[0] ==
'\0')
351 out_basename[0] =
'\0';
356 st =
copy_str(tmp,
sizeof(tmp), fname);
359 out_basename[0] =
'\0';
365 return (
int)
copy_str(out_basename, out_basename_sz, tmp);
関数動的呼び出し機構 (funcman) の公開 API ヘッダー。
get_lib_info_status_t
内部関数の戻り値(ステータス)。
@ MYLIB_EINVAL
引数不正 (NULL、サイズ0など)
@ MYLIB_EFAIL
その他の失敗 (取得不能、OS API 失敗など)
@ MYLIB_ENOBUFS
バッファ不足 (出力が収まらない)
int get_lib_basename(char *out_basename, const size_t out_basename_sz, const void *func_addr)
指定した関数が所属する共有ライブラリ (.so/.dll) の basename (パスなし・拡張子なし) を取得します。
static get_lib_info_status_t get_self_path_posix(char *out_path, size_t out_path_sz, const void *func_addr)
.so 自身の絶対パスを取得します (Linux/Unix)。
static void strip_extension_inplace(char *s)
拡張子を取り除きます (その場で書き換え)。
static get_lib_info_status_t copy_str(char *dst, size_t dst_sz, const char *src)
文字列を安全にコピーします (UTF-8 想定だが単なる byte 列として扱う)。
static const char * get_ilename_part(const char *path)
パス文字列からファイル名部分 (最後の区切り文字以降) を返します。
int get_lib_path(char *out_path, const size_t out_path_sz, const void *func_addr)
指定した関数が所属する共有ライブラリ (.so/.dll) の絶対パスを取得します。