dlopen

Autres langues

Langue: ja

Version: 2003-11-17 (openSuse - 09/10/07)

Section: 3 (Bibliothèques de fonctions)

̾Á°

dlclose, dlerror, dlopen, dlsym - ưŪ¥ê¥ó¥¯¤ò¹Ô¤¦¥í¡¼¥À¤Ø¤Î ¥×¥í¥°¥é¥ß¥ó¥°¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹

½ñ¼°

#include <dlfcn.h>

void *dlopen(const char *filename, int flag);

char *dlerror(void);

void *dlsym(void *handle, const char *symbol);

int dlclose(void *handle);

ÀâÌÀ

dlopen(), dlsym(), dlclose(), dlerror() ¤Î 4¤Ä¤Î´Ø¿ô¤Ï¡¢Æ°Åª¥ê¥ó¥¯ (dynamic linking) ¤ò¹Ô¤¦¥í¡¼¥À¤Ø¤Î ¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤ò¼ÂÁõ¤·¤¿¤â¤Î¤Ç¤¢¤ë¡£

dlerror

´Ø¿ô dlerror() ¤Ï¡¢Á°²ó dlerror() ¤¬¸Æ¤Ó½Ð¤µ¤ì¤¿¸å¤Ë¡¢ dlopen(), dlsym(), dlclose() ¤Î¤¤¤º¤ì¤«¤ÇºÇ¸å¤ËȯÀ¸¤·¤¿¥¨¥é¡¼¤Ë¤Ä¤¤¤Æ¤ÎÀâÌÀ¥á¥Ã¥»¡¼¥¸¤òÊÖ¤¹¡£ ½é´ü²½¸å¤Þ¤¿¤ÏÁ°²ó¸Æ¤Ó½Ð¤µ¤ì¤¿¸å¤Ç¡¢¥¨¥é¡¼¤¬È¯À¸¤·¤Æ¤¤¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£

dlopen

´Ø¿ô dlopen() ¤Ï¡¢NULL ½ªÃ¼¤µ¤ì¤¿Ê¸»úÎó filename ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë̾¤ÎưŪ¥é¥¤¥Ö¥é¥ê (dynamic library) ¤ò¥í¡¼¥É¤·¡¢ ¤½¤ÎưŪ¥é¥¤¥Ö¥é¥ê¤Ø¤ÎÆâÉô¡Ö¥Ï¥ó¥É¥ë¡×¤òÊÖ¤¹¡£ filename ¤¬ NULL ¤Î¾ì¹ç¡¢¥á¥¤¥ó¡¦¥×¥í¥°¥é¥à¤Ø¤Î¥Ï¥ó¥É¥ë¤¬ÊÖ¤µ¤ì¤ë¡£ filename ¤¬¥¹¥é¥Ã¥·¥å ("/") ¤ò´Þ¤à¾ì¹ç¡¢(ÁêÂФ«ÀäÂФ«¤Î)¥Ñ¥¹Ì¾¤È¤·¤Æ²ò¼á¤µ¤ì¤ë¡£ ¤½¤ì°Ê³°¤Î¾ì¹ç¡¢Æ°Åª¥ê¥ó¥«¤Ï°Ê²¼¤Î¼ê½ç¤Ç¥é¥¤¥Ö¥é¥ê¤ò¸¡º÷¤¹¤ë (¾ÜºÙ¤Ï ld.so(8) ¤ò»²¾È):
o
(ELF ¤Î¤ß) ¸Æ¤Ó½Ð¤·¸µ¥×¥í¥°¥é¥à¤Î¼Â¹Ô¥Õ¥¡¥¤¥ë¤Ë DT_RPATH ¥¿¥°¤¬´Þ¤Þ¤ì¤Æ¤ª¤ê¡¢ DT_RUNPATH ¥¿¥°¤¬´Þ¤Þ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¡¢DT_RPATH ¥¿¥°¤Ë½ñ¤«¤ì¤Æ¤¤¤ë ¥Ç¥£¥ì¥¯¥È¥ê¡¦¥ê¥¹¥È¤ò¸¡º÷¤¹¤ë¡£
o
´Ä¶­ÊÑ¿ô ¤Ç»ØÄꤵ¤ì¤¿¥³¥í¥ó¶èÀÚ¤ê¤Î¥Ç¥£¥ì¥¯¥È¥ê¡¦¥ê¥¹¥È¤ò¸¡º÷¤¹¤ë¡£ (¥»¥­¥å¥ê¥Æ¥£¾å¤ÎÍýͳ¤Ç¡¢¤³¤ÎÊÑ¿ô¤Ï set-UID ¤ä set-GID ¤µ¤ì¤¿ ¥×¥í¥°¥é¥à¤Î¾ì¹ç¤Ï̵»ë¤µ¤ì¤ë)
o
(ELF ¤Î¤ß) ¸Æ¤Ó½Ð¤·¸µ¥×¥í¥°¥é¥à¤Î¼Â¹Ô¥Õ¥¡¥¤¥ë¤Ë DT_RUNPATH ¥¿¥°¤¬´Þ¤Þ¤ì¤Æ ¤¤¤ë¾ì¹ç¡¢¤½¤Î¥¿¥°¤Ë½ñ¤«¤ì¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥È¥ê¡¦¥ê¥¹¥È¤ò¸¡º÷¤¹¤ë¡£
o
¥­¥ã¥Ã¥·¥å¥Õ¥¡¥¤¥ë /etc/ld.so.cache ¤ÎÃæ¤Ë filename ¤Î¥¨¥ó¥È¥ê¤¬Æþ¤Ã¤Æ¤¤¤ë¤«¤ò¥Á¥§¥Ã¥¯¤¹¤ë (/etc/ld.so.cache ¤Ï ldconfig(8) ¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤¤¤ë)¡£
o
¥Ç¥£¥ì¥¯¥È¥ê /lib ¤È /usr/lib ¤ò¤³¤Î½çÈ֤Ǹ¡º÷¤¹¤ë¡£

¤½¤Î¥é¥¤¥Ö¥é¥ê¤¬Â¾¤Î¶¦Í­¥é¥¤¥Ö¥é¥ê¤Ë°Í¸¤·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ °Í¸¤·¤Æ¤¤¤ë¥é¥¤¥Ö¥é¥ê¤âưŪ¥ê¥ó¥«¤¬Æ±¤¸¸¡º÷¥ë¡¼¥ë¤Ë´ð¤Å¤¤¤Æ ¼«Æ°Åª¤Ë¥í¡¼¥É¤¹¤ë (¤½¤ì¤é¤Î¥é¥¤¥Ö¥é¥ê¤Ë¤µ¤é¤Ë°Í¸´Ø·¸¤¬¤¢¤ë¾ì¹ç¤Ê¤É¤Ï ¤³¤Î½èÍý¤ÏºÆµ¢Åª¤Ë¹Ô¤ï¤ì¤ë)¡£

flag ¤Ë¤Ï°Ê²¼¤Î 2 ¤Ä¤ÎÃͤΤ¤¤º¤ì¤«¤ò´Þ¤á¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤:

RTLD_LAZY
lazy binding (¼êÈ´¤­¤Ê¥·¥ó¥Ü¥ë¤Î·ë¤ÓÉÕ¤±) ¤¬¹Ô¤¦¡£ ¥·¥ó¥Ü¥ë¤Î²ò·è¤Ï¤½¤Î¥·¥ó¥Ü¥ë¤ò»²¾È¤¹¤ë¥³¡¼¥É¤¬¼Â¹Ô¤µ¤ì¤ë¤È¤­¤Ë¤Î¤ß ¹Ô¤ï¤ì¤ë¡£¥·¥ó¥Ü¥ë¤¬°ìÅ٤⻲¾È¤µ¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥·¥ó¥Ü¥ë¤Ï ²ò·è¤µ¤ì¤Ê¤¤¤Þ¤Þ¤È¤Ê¤ë¡£ (lazy binding ¤Ï´Ø¿ô»²¾È¤Ë¤Ä¤¤¤Æ¤Î¤ß¼Â»Ü¤µ¤ì¤ë; ÊÑ¿ô¤Ø¤Î»²¾È¤Ï¾ï¤Ë ¥é¥¤¥Ö¥é¥ê¤¬¥í¡¼¥É¤µ¤ì¤¿»þÅÀ¤Çľ¤Á¤Ë²ò·è¤µ¤ì¤ë¡£)
RTLD_NOW
¤³¤ÎÃͤ¬»ØÄꤵ¤ì¤ë¤«¡¢´Ä¶­ÊÑ¿ô LD_BIND_NOW ¤Ë¶õ¤Ç¤Ê¤¤Ê¸»úÎó¤¬ÀßÄꤵ¤ì¤¿¾ì¹ç¡¢ ¥é¥¤¥Ö¥é¥êÃæ¤Î̤ÄêµÁ¤Î¥·¥ó¥Ü¥ë¤òÁ´¤Æ²ò·è¤·¤Æ¤«¤é dlopen() ¤ÏÉüµ¢¤¹¤ë¡£²ò·è¤Ç¤­¤Ê¤«¤Ã¤¿¤È¤­¤Ë¤Ï¥¨¥é¡¼¤¬ÊÖ¤µ¤ì¤ë¡£

°Ê²¼¤ÎÃͤΤ¦¤Á 0 ¸Ä°Ê¾å¤òÏÀÍýÏ (OR) ¤Î·Á¤Ç flag ¤ËÄɲ乤뤳¤È¤â¤Ç¤­¤ë:

RTLD_GLOBAL
¤³¤Î¥é¥¤¥Ö¥é¥ê¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥·¥ó¥Ü¥ë¤¬¡¢¤³¤ì¤è¤ê¸å¤Ç¥í¡¼¥É¤µ¤ì¤ë ¥é¥¤¥Ö¥é¥ê¤Î¥·¥ó¥Ü¥ë²ò·è¤ÇÍøÍѤǤ­¤ë¤è¤¦¤Ë¤Ê¤ë¡£
RTLD_LOCAL
¤³¤Î¥Õ¥é¥°¤Ï RTLD_GLOBAL ¤ÎÈ¿ÂФΰÕÌ£¤Ç¤¢¤ê¡¢¤É¤Á¤é¤Î¥Õ¥é¥°¤â»ØÄꤵ¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï ¤³¤Á¤é¤¬¥Ç¥Õ¥©¥ë¥È¤È¤Ê¤ë¡£ ¤³¤Î¥é¥¤¥Ö¥é¥ê¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥·¥ó¥Ü¥ë¤Ï¡¢¤³¤ì¤è¤ê¸å¤Ç¥í¡¼¥É¤µ¤ì¤ë ¥é¥¤¥Ö¥é¥ê¤Ç¤Î¥·¥ó¥Ü¥ë»²¾È¤ÇÍøÍѤǤ­¤Ê¤¤¡£
RTLD_NODELETE (glibc 2.2 °Ê¹ß)
dlclose() Ãæ¤Ë¤½¤Î¥é¥¤¥Ö¥é¥ê¤ò¥¢¥ó¥í¡¼¥É¤·¤Ê¤¤¡£ ¤½¤Î¤¿¤á¡¢Æ±¤¸¥é¥¤¥Ö¥é¥ê¤ò¤³¤ì°Ê¹ß¤Ë dlopen() ¤ÇºÆÅÙ¥í¡¼¥É¤·¤¿¾ì¹ç¤Ë¡¢¥é¥¤¥Ö¥é¥êÆâ¤ÎÀÅŪÊÑ¿ô¤ÏºÆ½é´ü²½¤µ¤ì¤Ê¤¤¡£ ¤³¤Î¥Õ¥é¥°¤Ï POSIX.1-2001 ¤Ç¤Ïµ¬Äꤵ¤ì¤Æ¤¤¤Ê¤¤¡£
RTLD_NOLOAD (glibc 2.2 °Ê¹ß)
¤½¤Î¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤·¤Ê¤¤¡£ ¤³¤Î¥Õ¥é¥°¤Ï¤½¤Î¥é¥¤¥Ö¥é¥ê¤¬¤¹¤Ç¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë¤«¤ò¸¡ºº¤¹¤ë¤Î¤Ë ÍøÍѤǤ­¤ë (dlopen() ¤Ï¡¢¥é¥¤¥Ö¥é¥ê¤¬ÁȤ߹þ¤Þ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤·¡¢ ¤¹¤Ç¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ì¤Ð¤½¤Î¥é¥¤¥Ö¥é¥ê¤Î¥Ï¥ó¥É¥ë¤òÊÖ¤¹)¡£ ¤Þ¤¿¡¢¤¹¤Ç¤Ë¥í¡¼¥É¤µ¤ì¤Æ¤¤¤ë¥é¥¤¥Ö¥é¥ê¤Î¥Õ¥é¥°¤ò¾º³Ê¤µ¤»¤ë¤Î¤Ë¤â ÍøÍѤǤ­¤ë¡£Î㤨¤Ð¡¢²áµî¤Ë RTLD_LOCAL ¤Ç¥í¡¼¥É¤·¤¿¥é¥¤¥Ö¥é¥ê¤ò RTLD_NOLOAD | RTLD_GLOBAL ¤ÇºÆ¥ª¡¼¥×¥ó¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£ ¤³¤Î¥Õ¥é¥°¤Ï POSIX.1-2001 ¤Ç¤Ïµ¬Äꤵ¤ì¤Æ¤¤¤Ê¤¤¡£
RTLD_DEEPBIND (glibc 2.3.4 °Ê¹ß)
¤³¤Î¥é¥¤¥Ö¥é¥êÆâ¤Î¥·¥ó¥Ü¥ë¤Î»²¾ÈÎΰè¤ò¥°¥í¡¼¥Ð¥ëÎΰè¤è¤ê¤âÁ°¤ËÇÛÃÖ¤¹¤ë¡£ ¤Ä¤Þ¤ê¡¢Æ⢷¿¤Î¥é¥¤¥Ö¥é¥ê¤Ç¤Ï¡¢¤¹¤Ç¤Ë¥í¡¼¥É¤µ¤ì¤¿¥é¥¤¥Ö¥é¥ê¤Ë´Þ¤Þ¤ì¤ë Ʊ¤¸Ì¾Á°¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥·¥ó¥Ü¥ë¤è¤ê¤â¼«¥é¥¤¥Ö¥é¥êÆâ¤Î¥·¥ó¥Ü¥ë¤¬Í¥À褷¤Æ »È¤ï¤ì¤ë¡£ ¤³¤Î¥Õ¥é¥°¤Ï POSIX.1-2001 ¤Ç¤Ïµ¬Äꤵ¤ì¤Æ¤¤¤Ê¤¤¡£

filename ¤¬ NULL ¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¾ì¹ç¤Ï¡¢ ÊÖ¤µ¤ì¤ë¥Ï¥ó¥É¥ë¤Ï¥á¥¤¥ó¡¦¥×¥í¥°¥é¥à¤Î¤â¤Î¤Ë¤Ê¤ë¡£ ¤³¤Î¥Ï¥ó¥É¥ë¤¬ dlsym() ¤ËÅϤµ¤ì¤ë¤È¡¢¥·¥ó¥Ü¥ë¤Î¸¡º÷¤Ï¡¢¥á¥¤¥ó¡¦¥×¥í¥°¥é¥àÆâ¡¢ ¥×¥í¥°¥é¥à¤Îµ¯Æ°»þ¤Ë¥í¡¼¥É¤µ¤ì¤ëÁ´¤Æ¤Î¶¦Í­¥é¥¤¥Ö¥é¥ê¡¢ dlopen() ¤Ë¤è¤Ã¤Æ RTLD_GLOBAL ¥Õ¥é¥°ÉÕ¤­¤Ç¥í¡¼¥É¤µ¤ì¤¿Á´¤Æ¤Î¶¦Í­¥é¥¤¥Ö¥é¥ê¡¢¤Î½ç½ø¤Ç¹Ô¤ï¤ì¤ë¡£

¥ª¡¼¥×¥ó¤µ¤ì¤¿¥é¥¤¥Ö¥é¥êÃæ¤Ç¤Î³°Éô»²¾È¤Ï¡¢ ¤½¤Î¥é¥¤¥Ö¥é¥ê¤Î°Í¸¥ê¥¹¥È¤Ë¤¢¤ë¥é¥¤¥Ö¥é¥ê¤«¡¢ RTLD_GLOBAL ¥Õ¥é¥°ÉÕ¤­¤Ç´û¤Ë¥ª¡¼¥×¥ó¤µ¤ì¤Æ¤¤¤ë¥é¥¤¥Ö¥é¥ê¤ò»È¤Ã¤Æ²ò·è¤µ¤ì¤ë¡£ ¼Â¹Ô¥Õ¥¡¥¤¥ë¤¬ "-rdynamic" ¥Õ¥é¥° ("--export-dynamic" ¤âƱµÁ) ÉÕ¤­¤Ç¥ê¥ó¥¯¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¼Â¹Ô¥Õ¥¡¥¤¥ëÃæ¤Î¥°¥í¡¼¥Ð¥ë¥·¥ó¥Ü¥ë¤â¡¢ ưŪ¤Ë¥í¡¼¥É¤µ¤ì¤ë¥é¥¤¥Ö¥é¥êÆâ¤Î»²¾È²ò·è¤ËÍѤ¤¤é¤ì¤ë¡£

Ʊ¤¸¥é¥¤¥Ö¥é¥ê¤¬ dlopen() ¤Ë¤è¤Ã¤ÆºÆÅÙ¥í¡¼¥É¤µ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢Æ±¤¸¥Õ¥¡¥¤¥ë¥Ï¥ó¥É¥ë¤¬ÊÖ¤µ¤ì¤ë¡£ dl ¥é¥¤¥Ö¥é¥ê¤Ï¥é¥¤¥Ö¥é¥ê¥Ï¥ó¥É¥ë¤Î¥ê¥ó¥¯¿ô¤ò´ÉÍý¤·¤Æ¤¤¤ë¡£ ¤·¤¿¤¬¤Ã¤ÆưŪ¥é¥¤¥Ö¥é¥ê¤Ï dlclose() ¤¬ dlopen() ¤ÈƱ¤¸²ó¿ô¤À¤±¸Æ¤Ó½Ð¤µ¤ì¤Ê¤¤¸Â¤ê¥¢¥ó¥í¡¼¥É¤µ¤ì¤Ê¤¤¡£ _init ¥ë¡¼¥Á¥ó¤Ï°ìÅÙ¤À¤±¸Æ¤Ó½Ð¤µ¤ì¤ë (_init ¤¬Â¸ºß¤¹¤ë¾ì¹ç¤Î¤ß)¡£ RTLD_NOW ¤¬»ØÄꤵ¤ì¤Æ dlopen() ¤¬¸Æ¤Ó½Ð¤µ¤ì¤¿¾ì¹ç¡¢ RTLD_LAZY ¤Ç°ÊÁ°¤Ë¥í¡¼¥É¤µ¤ì¤¿¥é¥¤¥Ö¥é¥ê¤Î¥·¥ó¥Ü¥ë²ò·è¤¬¼Â¹Ô¤µ¤ì¤ë¤³¤È¤¬¤¢¤ë¡£

dlopen() ¤Ï¡¢²¿¤é¤«¤ÎÍýͳ¤Ç¼ºÇÔ¤¹¤ë¤È NULL ¤òÊÖ¤¹¡£

dlsym

´Ø¿ô dlsym() ¤Ï¡¢ dlopen() ¤¬ÊÖ¤·¤¿Æ°Åª¥é¥¤¥Ö¥é¥ê¤Î¡Ö¥Ï¥ó¥É¥ë¡×¤È¡¢ NULL ½ªÃ¼¤µ¤ì¤¿¥·¥ó¥Ü¥ë̾¤Îʸ»úÎó¤ò°ú¤­¿ô¤Ë¼è¤ê¡¢ ¤½¤Î¥·¥ó¥Ü¥ë¤¬¥í¡¼¥É¤µ¤ì¤¿¥á¥â¥ê¤Î¥¢¥É¥ì¥¹¤òÊÖ¤¹¡£ ¥·¥ó¥Ü¥ë¤¬¡¢»ØÄꤵ¤ì¤¿¥é¥¤¥Ö¥é¥ê¤È¡¢»ØÄꤵ¤ì¤¿¥é¥¤¥Ö¥é¥ê¤¬¥í¡¼¥É¤µ¤ì¤ëºÝ¤Ë dlopen() ¤¬¼«Æ°Åª¤Ë¥í¡¼¥É¤·¤Æ¥é¥¤¥Ö¥é¥ê¤Î¤¤¤º¤ì¤Ë¤â¸«¤Ä¤«¤é¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢ dlsym() ¤Ï NULL ¤òÊÖ¤¹ (dlsym() ¤Ë¤è¤ë¸¡º÷¤Ï¡¢¤³¤ì¤é¤Î¥é¥¤¥Ö¥é¥ê¤Î°Í¸´Ø·¸¤Î¥Ä¥ê¡¼¤òÀèƬ¤«¤é é¤Ã¤Æ¹Ô¤ï¤ì¤ë)¡£ ¼ÂºÝ¤Ë¤Ï¥·¥ó¥Ü¥ë¤ÎÃͼ«ÂΤ¬ NULL ¤Ë¤Ê¤ë¤³¤È¤â¤¢¤ë (¤½¤Î¤¿¤á¡¢ dlsym() ¤ÎÊÖ¤êÃͤ¬ NULL ¤Ç¤¢¤Ã¤¿¤È¤·¤Æ¤âɬ¤º¤·¤â¥¨¥é¡¼¤È¤¤¤¦Ìõ¤Ç¤Ï¤Ê¤¤)¡£ ¥¨¥é¡¼¤«¤É¤¦¤«¤ò³Îǧ¤¹¤ëÀµ¤·¤¤ÊýË¡¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë: dlerror() ¤ò¸Æ¤Ó½Ð¤·¤Æ°ÊÁ°¤Î¥¨¥é¡¼¾õÂÖ¤ò¥¯¥ê¥¢¤·¤Æ¤«¤é¡¢ dlsym() ¤ò¸Æ¤Ó½Ð¤¹¡£¤½¤Î¸å¤Ç¤â¤¦°ìÅÙ dlerror() ¤ò¸Æ¤Ó½Ð¤·¤Æ¡¢ dlerror() ¤ÎÊÖ¤êÃͤòÊÑ¿ô¤ËÊݸ¤·¡¢Êݸ¤·¤¿Ãͤ¬ NULL ¤Ç¤¢¤ë¤«È½Äꤹ¤ë¡£

RTLD_DEFAULT ¤È RTLD_NEXT ¤È¤¤¤¦Æó¤Ä¤ÎÆÃÊ̤ʵ¼»÷¥Ï¥ó¥É¥ë¤¬¤¢¤ë¡£ RTLD_DEFAULT ¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥é¥¤¥Ö¥é¥ê¸¡º÷½ç½ø¤Ë¤·¤¿¤¬¤Ã¤Æ¡¢ ¸¡º÷ÂоݤΥ·¥ó¥Ü¥ë¤¬ºÇ½é¤Ë¸½¤ì¤ë¤È¤³¤í¤òõ¤¹¡£ RTLD_NEXT ¤Ï¡¢¥é¥¤¥Ö¥é¥ê¸¡º÷½ç½ø¤ÎÃæ¤Ç¸½ºß¤Î¥é¥¤¥Ö¥é¥ê°Ê¹ß¤ÇºÇ½é¤Ë ´Ø¿ô¤¬¸½¤ì¤ë¤È¤³¤í¤òõ¤¹¡£¤³¤Îµ¡Ç½¤ò»È¤¦¤³¤È¤Ç¡¢Ê̤ζ¦Í­¥é¥¤¥Ö¥é¥ê¤Î ´Ø¿ô¤Ø¤Î¥é¥Ã¥Ñ¡¼¤òÄ󶡤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£

dlclose

´Ø¿ô dlclose() ¤ÏưŪ¥é¥¤¥Ö¥é¥ê¤Î¥Ï¥ó¥É¥ë handle ¤Î»²¾È¥«¥¦¥ó¥È¤ò 1 ¸º¤é¤¹¡£»²¾È¥«¥¦¥ó¥È¤¬ 0 ¤Ë¤Ê¤ê¡¢¥í¡¼¥É¤µ¤ì¤Æ¤¤¤ë ¾¤Î¥é¥¤¥Ö¥é¥ê¤«¤é¤½¤Î¥é¥¤¥Ö¥é¥êÆâ¤Î¥·¥ó¥Ü¥ë¤¬»È¤ï¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢ ¤½¤ÎưŪ¥é¥¤¥Ö¥é¥ê¤ò¥¢¥ó¥í¡¼¥É¤¹¤ë¡£

´Ø¿ô dlclose() ¤Ï¡¢À®¸ù¤·¤¿¾ì¹ç¤Ï 0 ¤òÊÖ¤·¡¢¥¨¥é¡¼¤Î¾ì¹ç 0 °Ê³°¤òÊÖ¤¹¡£

Çѻߤµ¤ì¤¿¥·¥ó¥Ü¥ë _init ¤È _fini

¥ê¥ó¥«¤Ï _init ¤È _fini ¤òÆÃÊ̤ʥ·¥ó¥Ü¥ë¤È²ò¼á¤¹¤ë¡£ ¤¢¤ëưŪ¥é¥¤¥Ö¥é¥ê¤Ç _init ¤È¤¤¤¦Ì¾Á°¤Î¥ë¡¼¥Á¥ó¤¬¥¨¥¯¥¹¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢ ¤½¤Î¥³¡¼¥É¤Ï¡¢¥é¥¤¥Ö¥é¥ê¤Î¥í¡¼¥É¸å¡¢¤«¤Ä dlopen() ¤¬Éüµ¢¤¹¤ëÁ°¤Ë¼Â¹Ô¤µ¤ì¤ë¡£ ¤½¤ÎưŪ¥é¥¤¥Ö¥é¥ê¤Ç _fini ¤È¤¤¤¦Ì¾Á°¤Î¥ë¡¼¥Á¥ó¤¬¥¨¥¯¥¹¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢ ¥é¥¤¥Ö¥é¥ê¤¬¥¢¥ó¥í¡¼¥É¤µ¤ì¤ëľÁ°¤Ë¤½¤Î¥ë¡¼¥Á¥ó¤¬¸Æ¤Ó½Ð¤µ¤ì¤ë¡£ ¥·¥¹¥Æ¥à¤Îµ¯Æ°¥Õ¥¡¥¤¥ë¤ËÂФ¹¤ë¥ê¥ó¥¯¤òÈò¤±¤ëɬÍפ¬¤¢¤ë¾ì¹ç¡¢ gcc ¤Î¥³¥Þ¥ó¥É¥é¥¤¥ó¤Ë "-nostartfiles" ¥ª¥×¥·¥ç¥ó¤ò»ØÄꤹ¤ì¤Ð¤è¤¤¡£

¤³¤Î¥ë¡¼¥Á¥ó¤ä¡¢gcc ¤Î¥ª¥×¥·¥ç¥ó -nostartfiles ¤ä -nostdlib ¤Ï»ÈÍѤ·¤Ê¤¤¤³¤È¤ò¿ä¾©¤¹¤ë¡£ ¤³¤ì¤é¤ò»È¤¦¤È¡¢Ë¾¤Þ¤·¤¯¤Ê¤¤Æ°ºî¤ò¤¹¤ë¤³¤È¤¬¤¢¤ë¡£ ¤Ê¤¼¤Ê¤é¡¢(ÆÃÊ̤ÊÁ¼ÃÖ¤¬¹Ô¤ï¤ì¤Ê¤¤¸Â¤ê) ¤³¤ì¤é¤Î constructor/destructor ¥ë¡¼¥Á¥ó¤Ï¼Â¹Ô¤µ¤ì¤Ê¤¤¤«¤é¤Ç¤¢¤ë¡£

Âå¤ï¤ê¤Ë¡¢¥é¥¤¥Ö¥é¥ê¤Ï __attribute__((constructor)) ¤ä __attribute__((destructor)) ¤Î´Ø¿ô°À­¤ò»È¤Ã¤ÆɬÍפʥ롼¥Á¥ó¤ò¥¨¥¯¥¹¥Ý¡¼¥È¤¹¤ë¤Î¤¬¤è¤¤¡£ ¤³¤ì¤é¤Ë¤Ä¤¤¤Æ¤Ï gcc ¤Î info ¥Ú¡¼¥¸¤ò»²¾È¤Î¤³¤È¡£ constructor ¥ë¡¼¥Á¥ó¤Ï dlopen() ¤¬Éüµ¢¤¹¤ëÁ°¤Ë¼Â¹Ô¤µ¤ì¡¢ destructor ¥ë¡¼¥Á¥ó¤Ï dlclose() ¤¬Éüµ¢¤¹¤ëÁ°¤Ë¼Â¹Ô¤µ¤ì¤ë¡£

GNU ¤Ç¤Î³ÈÄ¥: dladdr() ¤È dlvsym()

glibc ¤Ç¤Ï POSIX ¤Ë¤Ïµ­ºÜ¤µ¤ì¤Æ¤¤¤Ê¤¤´Ø¿ô¤¬ 2¤ÄÄɲ䵤ì¤Æ¤¤¤ë¡£ ¥×¥í¥È¥¿¥¤¥×¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡£

#define _GNU_SOURCE

#include <dlfcn.h>



int dladdr(void *addr, Dl_info *info);



void *dlvsym(void *handle, char *symbol, char *version);

´Ø¿ô dladdr() ¤Ï¡¢´Ø¿ô¤Î¥Ý¥¤¥ó¥¿¤ò°ú¤­¿ô¤Ë¤È¤ê¡¢´Ø¿ô¤Î̾Á°¤È´Ø¿ô¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë ¥Õ¥¡¥¤¥ë¤Î²ò·è¤ò»î¤ß¤ë¡£¾ðÊó¤Ï Dl_info ¹½Â¤ÂΤ˳ÊǼ¤µ¤ì¤ë¡£


typedef struct {

  const char *dli_fname;/* Filename of defining object */

  void *dli_fbase;      /* Load address of that object */

  const char *dli_sname;/* Name of nearest lower symbol */

  void *dli_saddr;      /* Exact value of nearest symbol */

} Dl_info;

dladdr() ¤Ï¡¢¥¨¥é¡¼»þ¤Ë¤Ï 0 ¤òÊÖ¤·¡¢À®¸ù¤·¤¿¾ì¹ç¤Ï 0 °Ê³°¤òÊÖ¤¹¡£

´Ø¿ô dlvsym() ¤Ï dlsym() ¤ÈƱ¤¸Æ°ºî¤ò¤¹¤ë¤¬¡¢¥Ð¡¼¥¸¥ç¥ó¤Îʸ»úÎó¤òÅϤ¹°ú¤­¿ô¤¬ Äɲ䵤ì¤Æ¤¤¤ëÅÀ¤¬°Û¤Ê¤ë¡£

½àµò

POSIX.1-2003 ¤Ë¤Ï dlclose(), dlerror(), dlopen(), dlsym(). ¤Îµ­ºÜ¤¬¤¢¤ë¡£

Ãí°Õ

¥·¥ó¥Ü¥ë RTLD_DEFAULT ¤È RTLD_NEXT ¤Ï <dlfcn.h> ¤ÇÄêµÁ¤µ¤ì¤Æ¤ª¤ê¡¢ <dlfcn.h> ¤Î¥¤¥ó¥¯¥ë¡¼¥ÉÁ°¤Ë _GNU_SOURCE ¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Î¤ßÍ­¸ú¤È¤Ê¤ë¡£

glibc 2.2.3 °Ê¹ß¤Ç¤Ï¡¢ atexit(3) ¤ò»È¤Ã¤Æ¡¢¥é¥¤¥Ö¥é¥ê¤¬¥¢¥ó¥í¡¼¥É¤µ¤ì¤ëºÝ¤Ë¼«Æ°Åª¤Ë¸Æ¤Ó½Ð¤µ¤ì¤ë ½ªÎ»¥Ï¥ó¥É¥é (exit handler) ¤òÅÐÏ¿¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£

Îò»Ë

dlopen ¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Îɸ½à¤Ï SunOS ¤ò¤â¤È¤Ë¤·¤Æ¤¤¤ë¡£ SunOS ¤Ë¤Ï dladdr() ¤â¤¢¤Ã¤¿¤¬¡¢ dlvsym() ¤Ï¤Ê¤«¤Ã¤¿¡£

Îã

math ¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤·¡¢2.0 ¤Î;¸¹¤òɽ¼¨¤¹¤ë



#include <stdio.h>

#include <stdlib.h>

#include <dlfcn.h>



int

main(int argc, char **argv)

{

    void *handle;

    double (*cosine)(double);

    char *error;



    handle = dlopen("libm.so", RTLD_LAZY);

    if (!handle) {

        fprintf(stderr, "%s\n", dlerror());

        exit(EXIT_FAILURE);

    }



    dlerror();    /* Clear any existing error */

    *(void **) (&cosine) = dlsym(handle, "cos");

    if ((error = dlerror()) != NULL)  {

        fprintf(stderr, "%s\n", error);

        exit(EXIT_FAILURE);

    }



    printf("%f\n", (*cosine)(2.0));

    dlclose(handle);

    exit(EXIT_SUCCESS);

}

¤³¤Î¥×¥í¥°¥é¥à¤ò "foo.c" ¤Ë½ñ¤¤¤¿¤È¤¹¤ë¤È¡¢°Ê²¼¤Î¥³¥Þ¥ó¥É¤Ç¥×¥í¥°¥é¥à¤ò ¥Ó¥ë¥É¤Ç¤­¤ë¡£


gcc -rdynamic -o foo foo.c -ldl

_init() ¤È _fini() ¤ò¥¨¥¯¥¹¥Ý¡¼¥È¤¹¤ë¥é¥¤¥Ö¥é¥ê¤Î¾ì¹ç¤Ï °Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¤¹¤ëɬÍפ¬¤¢¤ë¡£Îã¤È¤·¤Æ bar.c ¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¾ì¹ç:


gcc -shared -nostartfiles -o bar bar.c

´ØÏ¢¹àÌÜ

ld(1), ldd(1), dl_iterate_phdr(3), feature_test_macros(7), ld.so(8), ldconfig(8), ld.so info pages, gcc info pages, ld info pages