4. µ¿Àû ÀûÀç(DL) ¶óÀ̺귯¸®

µ¿Àû ÀûÀç ¶óÀ̺귯¸®´Â ÇÁ·Î±×·¥ÀÌ ½ÃÀÛÇÒ¶§°¡ ¾Æ´Ñ ´Ù¸¥ ½Ã±â¿¡ ÀûÀçµÇ´Â ¶óÀ̺귯¸®ÀÌ´Ù. À̰͵éÀº Ç÷¯±×ÀÎÀ̳ª ¸ðµâÀ» ±¸ÇöÇÒ¶§ ÀûÇÕÇÏ´Ù. ¿Ö³ÄÇÏ¸é ±×°ÍµéÀÌ ÇÊ¿äÇØÁú¶§±îÁö ÀûÀ縦 ±â´Ù¸± ¼ö Àֱ⠶§¹®ÀÌ´Ù. ¿¹¸¦µé¾î, PAM(Pluggable Authentication Modules)½Ã½ºÅÛÀº °ü¸®ÀÚ°¡ ÀÎÁõÀ» °ü¸®ÇÏ´Â °ÍÀ» Çã¿ëÇϱâ À§ÇØ DL¶óÀ̺귯¸®¸¦ »ç¿ëÇÑ´Ù. À̰͵éÀº ¶ÇÇÑ ¶§¶§·Î Äڵ带 ¸Ó½Å ÄÚµå·Î ¹Ù²Ù°í È¿À²À» À§ÇØ ¸ØÃßÁö ¾Ê°í ÄÄÆÄÀÏµÈ ÄÚµå·Î ¸¸µå´Â ÀÎÅÍÇÁ¸®Å͸¦ ±¸ÇöÇϴµ¥ À¯¿ëÇÏ´Ù. À̰ÍÀº ½Ç½Ã°£ÀÇ(just-in-time) ÄÄÆÄÀÏ·¯³ª MUD(multi-user dungeon)À» ±¸ÇöÇϴµ¥¿¡ À¯¿ëÇÏ´Ù.

¸®´ª½º¿¡¼­, DL ¶óÀ̺귯¸®´Â ±×µéÀÇ Æ÷¸äÀÇ °üÁ¡¿¡ À־ Ưº°ÇÏÁö ¾Ê´Ù; ±×µéÀº Ç¥ÁØÀÇ ¿ÀºêÁ§Æ® ÆÄÀÏ·Î ¸¸µé¾îÁö°Å³ª, À§¿¡¼­ ¾ð±ÞµÈ Ç¥ÁØÀÇ °øÀ¯ ¶óÀ̺귯¸® ÆÄÀÏ·Î ¸¸µé¾îÁø´Ù. ÁÖ¿ä Â÷ÀÌÁ¡Àº ÇÁ·Î±×·¥ÀÇ ¸µÅ©½Ã³ª ½ÃÀ۽ÿ¡ ÀûÀçµÇÁö ¾Ê´Â´Ù´Â °ÍÀÌ´Ù; ´ë½Å, ¶óÀ̺귯¸®¸¦ ¿­°Å³ª, ½Éº¼À» ã°Å³ª, ¿¡·¯¸¦ Á¶Á¤Çϰųª, ¶óÀ̺귯¸®¸¦ ´Ý´Â Ưº°ÇÑ API°¡ ÀÖ´Ù. C »ç¿ëÀÚµéÀº ÀÌ·± API¸¦ »ç¿ëÇϱâÀ§ÇØ dlfcn.h¶ó´Â Çì´õÆÄÀÏÀ» Æ÷ÇÔÇØ¾ß ÇÑ´Ù.

¸®´ª½º¿¡¼­ »ç¿ëµÇ´Â ÀÎÅÍÆäÀ̽º´Â ¼Ö¶ó¸®½º¿¡¼­ »ç¿ëµÇ´Â ÀÎÅÍÆäÀ̽º¿Í °°´Ù. À̰ÍÀ» ³ª´Â ``dlopen()'' API¶ó°í ºÒ¸¦ °ÍÀÌ´Ù. ±×·¯³ª, ÀÌ °°Àº ÀÎÅÍÆäÀ̽º°¡ ¸ðµç Ç÷§Æû¿¡¼­ Áö¿øµÇ´Â °ÍÀº ¾Æ´Ï´Ù; HP-UX´Â shl_load()¹æ¹ýÀ» »ç¿ëÇϰí, À©µµ¿ìÁî´Â ¿ÏÀüÈ÷ ´Ù¸¥ ÀÎÅÍÆäÀ̽ºÀÇ DLLsÀ» »ç¿ëÇÑ´Ù. ¸¸¾à ´ç½ÅÀÌ Æø³ÐÀº Æ÷ÆÃ¼ºÀÌ ¸ñÇ¥¶ó¸é, ´ç½ÅÀº ÀÌ·± ´Ù¸¥ Ç÷§ÆûÀ» ¼û±â´Â ¶óÀ̺귯¸®¸¦ »ý°¢ÇØ¾ß ÇÒ°ÍÀÌ´Ù. ÇϳªÀÇ ¹æ¹ýÀº ¸ðµâÀÇ µ¿Àû ÀûÀ縦 Áö¿øÇÏ´Â glib ¶óÀ̺귯¸®ÀÌ´Ù; ±×°ÍÀº ÀÌ ÇÔ¼öµéÀÇ Æ÷ÆÃ°¡´ÉÇÑ ÀÎÅÍÆäÀ̽º¸¦ ±¸ÇöÇϱâÀ§ÇØ Ç÷§ÆûÀÇ µ¿Àû ÀûÀç ·çÆ¾À» »ç¿ëÇÑ´Ù. http://developer.gnome.org/doc/API/glib/glib-dynamic-loading-of-modules.htmlÀÇ ¸µÅ©¿¡¼­ glib¿¡ ´ëÇØ ¸¹Àº °ÍÀ» ã¾Æº¼ ¼ö ÀÖ´Ù. glib ÀÎÅÍÆäÀ̽º°¡ ÀÌ ¹®¼­¿¡ Àß ¼³¸íµÇÀֱ⠶§¹®¿¡ ´õ ¾ð±ÞÇÏÁö ¾Ê°Ú´Ù. ´Ù¸¥ ¹æ¹ýÀº GNU libtoolÀÇ ÀϺÎÀÎ libltdlÀ» »ç¿ëÇÏ´Â °ÍÀÌ´Ù. ´ç½ÅÀÌ À̰ͺ¸´Ù ´õ ±â´ÉÀûÀΰÍÀ» ¿øÇÑ´Ù¸é, CORBA ORB(Object Request Broker)¸¦ ã¾Æº¸¾Æ¶ó. ´ç½ÅÀÌ ¸®´ª½º¿Í ¼Ö¶ó¸®½º¿¡¼­ Á÷Á¢ Áö¿øµÇ´Â °ÍÀ» ¾ÆÁ÷µµ ¿øÇϰí ÀÖ´Ù¸é, °è¼Ó Àо°¡¶ó.

4.1. dlopen()

dlopen(3)ÇÔ¼ö´Â ¶óÀ̺귯¸®¸¦ ¿­°í ±×°ÍÀÌ »ç¿ëµÇµµ·Ï Áغñ½ÃÄÑÁØ´Ù. C¿¡¼­ ÇÁ·ÎÅäŸÀÔÀº ´ÙÀ½°ú °°´Ù:
  void * dlopen(const char *filename, int flag);
ÆÄÀÏÀ̸§ÀÌ ``/''(Áï, Àý´ë°æ·Î)·Î ½ÃÀÛÇÑ´Ù¸é dlopen()Àº Áï½Ã »ç¿ëÇÏ·Á ÇÑ´Ù(¶óÀ̺귯¸®¸¦ ãÀ¸·Á ÇÏÁö ¾Ê´Â´Ù). ±×·¸Áö ¾ÊÀ¸¸é, dlopen()Àº ´ÙÀ½°ú °°Àº ¼ø¼­·Î ¶óÀ̺귯¸®¸¦ ã´Â´Ù:

  1. »ç¿ëÀÚÀÇ LD_LIBRARY_PATHÀÇ È¯°æº¯¼öÀÇ ÄÝ·ÐÀ¸·Î ±¸ºÐÁö¾îÁø µð·ºÅ丮

  2. (/etc/ld.so.conf¿¡¼­ ÆÄ»ýµÈ) /etc/ld.so.cache¿¡ ¸í½ÃµÇ¾îÀÖ´Â ¶óÀ̺귯¸®ÀÇ ¸ñ·Ï

  3. /lib, /usr/lib. ¼ø¼­¸¦ ÁÖÀÇÇ϶ó; À̰ÍÀº ¿¹ÀüÀÇ a.out·Î´õ°¡ »ç¿ëÇÑ ¼ø¼­ÀÇ ¿ªÀÌ´Ù. ¿¹ÀüÀÇ a.out·Î´õ´Â ÇÁ·Î±×·¥À» ·ÎµåÇÒ¶§ /usr/libÀ» ã°í /libÀ» ã¾Ò´Ù(ld.so(8)ÀÇ manÆäÀÌÁö¸¦ Âü°íÇ϶ó). º¸ÅëÀº ¾î¶² µð·ºÅ丮³ª ´Ù¸¥µð·ºÅ丮 Çϳª¿¡¸¸ ¶óÀ̺귯¸®°¡ Àֱ⠶§¹®¿¡(µÑ´Ù ¾øÀ»¼öµµ ÀÖ´Ù) ¹®Á¦°¡ µÇÁö ¾Ê´Â´Ù. ±×¸®°í °°ÀºÀ̸§À» °¡Áø ´Ù¸¥ ¶óÀ̺귯¸®´Â ÀáÀçÀûÀÎ À§ÇèÀ» °¡Áö°í ÀÖ´Ù.

dlopen()¿¡¼­ flagÀÇ °ªÀº ``µ¿Àû ¶óÀ̺귯¸®°¡ ½ÇÇàµÇ¸é¼­ ÄÚµåÀÇ Á¤ÀǵÇÁö ¾ÊÀº ½Éº¼À» ó¸®Ç϶ó''ÀÇ Àǹ̸¦ °¡Áø RTLD_LAZYÀ̰ųª, ``dlopen()ÀÌ ¸®ÅÏÇϱâ Àü¿¡ ¸ðµç Á¤ÀǵÇÁö ¾ÊÀº ½Éº¼À» ó¸®Çϰí, ±×°ÍÀÌ µÇÁö ¾ÊÀ» °æ¿ì ½ÇÆÐÇ϶ó''ÀÇ Àǹ̸¦ Áö´Ñ RTLD_NOW°¡ ÀÖ´Ù. RTLD_GLOBALÀº flagÀÇ °ª¼Ó¿¡ ¿É¼ÇÀ¸·Î ¾µ¼ö ÀÖ´Ù. Àǹ̴ ¶óÀ̺귯¸®¿¡ ÀûÀçµÇ´Â ¿ÜºÎ ½Éº¼µéÀº ±× ÈÄ¿¡ ÀûÀçµÇ´Â ¶óÀ̺귯¸®¿¡ ÀÇÇØ¼­ °¡´ÉÇÏ´Ù´Â °ÍÀÌ´Ù. µð¹ö±ë½Ã¿¡, RTLD_NOW¸¦ ¾²±â¸¦ ¿øÇÒ°ÍÀÌ´Ù; RTLD_LAZY´Â Á¤ÀǵÇÁö ¾ÊÀº ½Éº¼ÀÌ ÀÖÀ¸¸é ¾Ë¾Æº¼¼ö ¾ø´Â ¿¡·¯¸¦ ³»±â ¶§¹®ÀÌ´Ù. RTLD_NOW¸¦ ¾²¸é¼­ ¶óÀ̺귯¸®¸¦ ¿©´Â °ÍÀº ¾à°£ÀÇ ½Ã°£ÀÌ ´õ °É¸°´Ù(ÇÏÁö¸¸ ³ªÁß¿¡ ã´Â ¼Óµµ´Â »¡¶óÁø´Ù); ¸¸¾à À̰ÍÀÌ À¯Àú ÀÎÅÍÆäÀ̽º ¹®Á¦¸¦ ÀÏÀ¸Å²´Ù¸é, ´ç½ÅÀº ³ªÁß¿¡ RTLD_LAZY·Î ¹Ù²Ü ¼ö ÀÖ´Ù.

¶óÀ̺귯¸®µéÀÌ ¼­·Î ÀÇÁ¸ÇÑ´Ù¸é(¿¹¸¦µé¾î X°¡ Y¿¡ ÀÇÁ¸ÇÑ´Ù¸é), ´ç½ÅÀº ÀÇÁ¸´çÇÏ´Â °ÍÀ» ¸ÕÀú ·ÎµåÇØ¾ßÇÑ´Ù(ÀÌ ¿¹Á¦¿¡¼­ Y¸¦ ·ÎµåÇϰí X¸¦ ·ÎµåÇØ¾ß ÇÑ´Ù).

dlopen()ÀÇ ¸®ÅÏ °ªÀº ´Ù¸¥ DL¶óÀ̺귯¸® ·çƾÀÌ »ç¿ëÇϱ⿡ ¾Ö¸Å¸ðÈ£ÇÏ°Ô ´À²¸Áö´Â ``ÇÚµé''ÀÌ´Ù. dlopen()Àº ·Îµå°¡ ¼º°øÇÏÁö ¸øÇϰųª ´ç½ÅÀÌ Ã¼Å©ÇØ¾ß ÇÒ Çʿ䰡 ÀÖ´Ù°í »ý°¢Çϸé NULLÀ» ¸®ÅÏÇÑ´Ù. dlopen()¿¡ ÀÇÇØ °°Àº ¶óÀ̺귯¸®°¡ ÇѹøÀÌ»ó ·ÎµåµÇ¸é °°Àº ÆÄÀÏ ÇÚµéÀÌ ¸®ÅϵȴÙ.

¶óÀ̺귯¸®°¡ _initÀ̶ó À̸§Áö¾îÁø ·çƾÀ» »ç¿ëÇÑ´Ù¸é(export), ±× ÄÚµå´Â dlopen()ÀÌ ¹ÝȯÇϱâ Àü¿¡ ½ÇÇàµÈ´Ù. ´ç½ÅÀº ÃʱâÈ­ ·çƾÀ» ±¸ÇöÇϱâÀ§ÇØ ´ç½ÅÀÇ ¶óÀ̺귯¸®¿¡¼­ ÀÌ »ç½ÇÀ» »ç¿ëÇßÀ»°ÍÀÌ´Ù. ´õ ÀÚ¼¼ÇÑ ³»¿ëÀ» À§ÇØ 5.2ÀýÀ» º¸¾Æ¶ó.

4.2. dlerror()

¿¡·¯´Â dlerror()¸¦ È£ÃâÇÔÀ¸·Î½á º¸°íµÉ¼ö ÀÖ´Ù. dlerror()´Â dlerror(), dlsym(), dlclose()Áß ¸¶Áö¸· ºÎ¸¥°ÍÀÇ ¿¡·¯ÀÇ ½ºÆ®¸µÀ» ¹ÝȯÇÑ´Ù. ÇϳªÀÇ ÀÌ»óÇÑÁ¡Àº dlerror()¸¦ ºÎ¸£°í ³ª¼­ dlerror()¸¦ ºÎ¸£´Â °ÍÀº ±× »çÀÌ¿¡ ´Ù¸¥ ¿¡·¯°¡ ¾øÀ¸¸é NULLÀ» ¹ÝȯÇÑ´Ù´Â °ÍÀÌ´Ù.

4.3. dlsym()

´ç½ÅÀÌ »ç¿ëÇÒ ¼ö ¾ø´Ù¸é DL¶óÀ̺귯¸®¸¦ ·ÎµùÇÏ´Â Àǹ̰¡ ¾ø´Ù. DL¶óÀ̺귯¸®¸¦ »ç¿ëÇÏ´Â Áß¿äÇÑ ·çƾÀº dlsym(3)ÀÌ´Ù. À̰ÍÀº ¿­·ÁÁø ¶óÀ̺귯¸®ÀÇ ½Éº¼ÀÇ °ªÀ» ã¾ÆÁØ´Ù. ÀÌ ÇÔ¼ö´Â ´ÙÀ½°ú °°ÀÌ Á¤ÀǵȴÙ:
 void * dlsym(void *handle, char *symbol);
ÇÚµéÀº dlopen¿¡ ÀÇÇØ ¹ÝȯµÈ °ªÀ̰í, ½Éº¼Àº NIL·Î ³¡³ª´Â ½ºÆ®¸µÀÌ´Ù. ´ç½ÅÀÌ ÇÒ ¼ö ÀÖ´Ù¸é ÀÖ´Ù¸é, dlsym()ÀÇ °á°ú¸¦ void* Æ÷ÀÎÅÍ·Î ÀúÀåÇÏÁö ¸¶¶ó. ¿Ö³ÄÇϸé, ´ç½ÅÀº »ç¿ëÇÒ¶§¸¶´Ù ij½ºÆ®Çؼ­ »ç¿ëÇØ¾ß Çϱ⶧¹®ÀÌ´Ù(±×¸®°í ´Ù¸¥»ç¶÷µéÀÌ ÇÁ·Î±×·¥À» À¯ÁöÇϴµ¥¿¡ ´õ ÀûÀº Á¤º¸¸¦ ÁÙ°ÍÀÌ´Ù).

dlsym()Àº ½Éº¼ÀÌ ¾øÀ¸¸é NULLÀ» ¹ÝȯÇÒ °ÍÀÌ´Ù. ¸¸¾à ´ç½ÅÀÇ ½Éº¼¿¡ NULLÀ̳ª 0ÀÌ ¾ø´Ù´Â °ÍÀ» ¾Ë¸é ÁÁ°ÚÁö¸¸, ´ÙÀ½°ú °°Àº ÀáÀçÀûÀÎ ¹®Á¦°¡ ÀÖ´Ù: ´ç½ÅÀÌ ¹ÞÀº NULLÀÌ ¿¡·¯Àΰ¡, ¾Æ´Ï¸é ½Éº¼ÀÇ °ªÀÌ NULLÀΰ¡? Ç¥ÁØÀûÀÎ ÇØ°á¹ýÀº dlerror()¸¦ ºÎ¸£°í(Àü¿¡ ÀÖ´ø ¿¡·¯µéÀ» ¾ø¾Ø´Ù), dlsym()À» ºÒ·¯¼­ ½Éº¼ÀÇ °ªÀ» ºÎ¸£°í, dlerror()¸¦ ºÒ·¯¼­ ¿¡·¯°¡ ³µ´ÂÁö üũÇÑ´Ù. ´Ü¼øÇÑ ÄÚµå´Â ´ÙÀ½°ú °°´Ù:
 dlerror(); /* clear error code */
 s = (actual_type) dlsym(handle, symbol_being_searched_for);
 if ((err = dlerror()) != NULL) {
  /* handle error, the symbol wasn't found */
 } else {
  /* symbol found, its value is in s */
 }

4.4. dlclose()

dlopen()ÀÇ ¹Ý´ë´Â dlclose()·Î¼­, DL ¶óÀ̺귯¸®¸¦ ´Ý¾ÆÁØ´Ù. DL ¶óÀ̺귯¸®°¡ µ¿Àû ÆÄÀÏ ÇÚµéÀÇ ¸µÅ© ¼ö¸¦ °ü¸®Çϱ⠶§¹®¿¡, µ¿Àû ¶óÀ̺귯¸®´Â dlopenÀÌ ¼º°øÇÑ ¸¸Å­ ¸ðµÎ dlclose¸¦ ºÒ·¯ÁÖ±â Àü¿¡ ´Ù ÇÒ´çÀÌ ¾ø¾îÁöÁö´Â ¾Ê´Â´Ù. µû¶ó¼­, °°Àº ÇÁ·Î±×·¥ÀÌ °°Àº ¶óÀ̺귯¸®¸¦ ¿©·¯¹ø ºÒ·¯Áִ°ÍÀº ¹®Á¦°¡ µÇÁö ¾Ê´Â´Ù. ¶óÀ̺귯¸®°¡ ÇÒ´çÀÌ ¾ø¾îÁø´Ù¸é, ÇÔ¼öÀÇ _fini°¡ ºÒ¸°´Ù(Á¸ÀçÇÑ´Ù¸é); ´õ ÀÚ¼¼ÇÑ Á¤º¸¸¦ À§ÇØ 5.2Àý¸¦ º¸¾Æ¶ó. ÁÖÀÇÇ϶ó : dlclose()´Â ¼º°øÇϸé 0À» ¸®ÅÏÇϰí, ¾Æ´Ï¸é 0ÀÌ ¾Æ´Ñ °ªÀ» ¸®ÅÏÇÑ´Ù; ¾î¶² ¸®´ª½º ¸Þ´º¾óÀº À̰ÍÀ» ¾ð±ÞÇϰí ÀÖÁö ¾Ê´Ù.

4.5. DL ¶óÀ̺귯¸® ¿¹Á¦

¿©±â¿¡ ÀÖ´Â ¿¹Á¦´Â dlopen(3)ÀÇ ¸ÇÆäÀÌÁö¿¡ ³ª¿À´Â ¿¹Á¦ÀÌ´Ù. ÀÌ ¿¹Á¦´Â math¶óÀ̺귯¸®¸¦ ·ÎµåÇØ¼­, ÄÚ»çÀÎ 2.0À» Ãâ·ÂÇÑ´Ù. ¶ÇÇÑ, °¢°¢ÀÇ ´Ü°è¿¡¼­ ¿¡·¯ üũ¸¦ ÇÑ´Ù(ÀÌ·¸°Ô Çϱ⸦ ÃßõÇÑ´Ù).

    #include <stdlib.h>
    #include <stdio.h>
    #include <dlfcn.h>

    int main(int argc, char **argv) {
        void *handle;
        double (*cosine)(double);
        char *error;

        handle = dlopen ("/lib/libm.so.6", RTLD_LAZY);
        if (!handle) {
            fputs (dlerror(), stderr);
            exit(1);
        }

        cosine = dlsym(handle, "cos");
        if ((error = dlerror()) != NULL)  {
            fputs(error, stderr);
            exit(1);
        }

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

¸¸¾à ÀÌ ÇÁ·Î±×·¥ÀÇ ÆÄÀÏÀ̸§ÀÌ "foo.c"¶ó¸é, ´ÙÀ½°ú °°Àº ¸í·ÉÀ¸·Î ÇÁ·Î±×·¥À» ¸¸µé ¼ö ÀÖÀ» °ÍÀÌ´Ù:
    gcc -o foo foo.c -ldl