ÇÁ·Î±×·¥À» ©¶§ DLL·Î ¸¸µé¸é ¸Þ¸ð¸®°¡ Àý¾à µÇ±â ¶§¹®¿¡ DLLÀ» »ç¿ë ÇÒ±î? ±×·¸Áö ¾Ê´Ù. ¿î¿µÃ¼Á¦³ª ÄÄÆ÷³ÍÆ®¸¦ ¸¸µå´Â°Ô ¾Æ´Ï¸é ¸Þ¸ð¸® Àý¾à µÇ´Â °æ¿ì´Â ¾ø´Ù. DLLÀ» »ç¿ëÇÏ´Â ÃÖ´ëÀÇ ÀÌÁ¡Àº ¸ðµâÈ°¡ ¾Æ´Ò±î ÇÑ´Ù. DLL·Î ¸¸µé°Ô µÇ¸é, ¼Ò½º°£ÀÇ Á¾¼Ó¼ºÀÌ ¸¹ÀÌ ÁÙ¾îµç´Ù.
DLL¿¡´Â ¹¬½ÃÀû ¸µÅ©¿Í ¸í½ÃÀû ¸µÅ©°¡ ÀÖ´Ù. ¹¬½ÃÀû ¸µÅ©´Â ÇÁ·Î±×·¥ÀÌ ½ÇÇà µÊ°ú µ¿½Ã¿¡ DLLÀÌ ·ÎµùµÈ´Ù. ¸í½ÃÀû ¸µÅ©´Â ¿ì¸®°¡ ¿øÇÏ´Â ½Ã±â¿¡ ·Îµù°ú ÇØÁ¦¸¦ ÇÒ ¼ö ÀÖ´Ù.
1. ¹¬½ÃÀû ¸µÅ© (dll_test1.zip)
DLLÀ» ¸¸µå´Âµ¥ »ç¿ëµÈ ÆÄÀÏÀº dllserver.h dllserver.cpp ÆÄÀÏÀÌ´Ù.
*.dllÀ» ¸¸µé¶§´Â __declspec(dllexport) ¼±¾ðÇØ ¿ÜºÎ·Î ³ëÃâ½Ãų Ŭ·¡½º³ª ÇÔ¼ö¸¦ ÁöÁ¤ÇÑ´Ù. Ŭ·¡½º CDllServer¸¦ ¿ÜºÎ·Î ¾Ë·ÁÁÖ±â À§ÇØ, ºñÁê¾ó ½ºÆ©µð¿ÀÀÇ "±¸¼º ¼Ó¼º - C/C++ - Àü󸮱â"¿¡ DLL_EXPORT¸¦ ¼±¾ðÇØÁÖ´Â ¹æ¹ýÀÌ Ã¹ ¹ø°°í , µÎ ¹ø°°¡ dllserver.cppÀÇ ¿¹¿Í °°ÀÌ #define DLL_EXPORT¸¦ ³Ö´Â ¹æ¹ýÀÌ ÀÖ´Ù.
__declspec(dllexport)¸¦ ¼±¾ðÇÏÁö ¾ÊÀ¸¸é ´ÙÀ½ ¿¡·¯°¡ ¶á´Ù.
f:\work\dll_test\dll_server\dllserver.cpp(5) : warning C4273: 'CDllServer::CDllServer' : dll ¸µÅ©°¡ ÀÏÄ¡ÇÏÁö ¾Ê½À´Ï´Ù.
~~~~~~~~~~~~~~~~~~~~~ Áß·« ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
¼Ó¼º - ±¸¼º ¼Ó¼º - ºôµå À̺¥Æ® - ºôµå ÈÄ À̺¥Æ® - ¸í·ÉÁÙ¿¡ ´ÙÀ½ ¸í·ÉÀ» Ãß°¡ÇÏ¿© ºôµå°¡ ³¡³ÈÄ dll_server.dllÀ» ÀÚµ¿À¸·Î º¹»çÇϵµ·Ï ÇÑ´Ù.
copy "$(SolutionDir)$(OutDir)\$(TargetFileName)" "..\dll_client\Debug\$(TargetFileName)"
|
1)DLL ¼Ò½º
//dllserver.h
#ifndef __DLLSERVER_H
#define __DLLSERVER_H
#ifdef DLL_EXPORT
#define DLL_DECLSPEC __declspec(dllexport)
#else
#define DLL_DECLSPEC __declspec(dllimport)
#endif
class DLL_DECLSPEC CDllServer
{
public:
CDllServer();
~CDllServer();
int Add(int num);
int Sub(int num);
int GetNum();
private:
int m_iSum;
};
#endif
|
//dllserver.cpp
#define DLL_EXPORT
#include "dllserver.h"
CDllServer::CDllServer()
{
m_iSum = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~ Áß ·« ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2) DLLÀ» È£ÃâÇÏ´Â ÇÁ·Î±×·¥
dllserver.h ÆÄÀÏÀÌ Æ÷Ç﵃ ¶§ DLL_EXPORT ¼±¾ðÀÌ ¾ÈµÇ¾î Àֱ⠶§¹®¿¡, DLL_DECLSPECÀº __declspec(dllimport)·Î º¯È¯µÈ´Ù.
ÇÔ¼ö ¼±¾ð¿¡¼ __declspec(dllimport)Àº »ç¿ëÇÏÁö ¾Ê¾Æµµ µÇÁö¸¸, ÀÌ Å°¿öµå¸¦ »ç¿ëÇϸé ÄÄÆÄÀÏ·¯¿¡¼ º¸´Ù È¿À²ÀûÀÎ Äڵ带 »ý¼ºÇÒ ¼ö ÀÖ½À´Ï´Ù. ±×·¯³ª ½ÇÇà ÆÄÀÏÀÌ DLLÀÇ °ø¿ë µ¥ÀÌÅÍ ±âÈ£ ¹× °³Ã¼¿¡ ¾×¼¼½ºÇÒ ¼ö ÀÖµµ·Ï ÇÏ·Á¸é __declspec(dllimport)À» »ç¿ëÇØ¾ß ÇÑ´Ù. ¹¬½ÃÀû ¸µÅ©¿¡¼ Ŭ·¡½º¸¦ »ç¿ëÇÏ´Â °æ¿ì, __declspec(dllimport)¸¦ »ç¿ëÇÏÁö ¾Ê´õ¶óµµ Äڵ带 »ý¼º ÇÒ ¼ö ÀÖ´Ù.
¹¬½ÃÀû ¸µÅ©´Â *.lib ÆÄÀÏÀ» Æ÷ÇÔ ½ÃÄÑ¾ß ÇÑ´Ù. ¶óÀ̺귯¸® ÆÄÀÏÀ» Æ÷ÇÔÇÏ´Â ¹æ¹ýÀº ¼¼°¡Áö°¡ ÀÖ´Ù.
¶óÀ̺귯¸® ÆÄÀÏ Æ÷ÇÔ ½ÃÅ°´Â ¹æ¹ý
. DLLÀÇ lib ÆÄÀÏÀ» ÇÁ·ÎÁ§Æ® ±¸¼º ¼Ó¼º¿¡ Á÷Á¢ Æ÷ÇÔ½ÃÅ°´Â ¹æ¹ý.
. DLL ÇÁ·ÎÁ§Æ®¿Í DLLÀ» È£ÃâÇÏ´Â ÇÁ·ÎÁ§Æ®¸¦ °°Àº ¼Ö·ç¼Ç¿¡ ÀÖÀ¸¸é ÀÚµ¿À¸·Î ¸µÅ©µÈ´Ù.
. #pragma comment(lib, "libÀ̸§") ¸¦ ¼Ò½º Äڵ忡 Æ÷ÇÔ ½ÃÅ°´Â ¹æ¹ý.
|
±×¸®°í ºôµå.....
//dll_client.cpp
#include <iostream>
#include "../dll_server/dllserver.h"
void main()
{
CDllServer test;
test.Add(1);
test.Add(2);
test.Add(3);
test.Sub(5);
std::cout << "Value is " << test.GetNum() << std::endl;
getchar();
}
|
2. ¸í½ÃÀû ¸µÅ© dll_test2.zip
¾Æ·¡´Â ÇÔ¼ö È£Ã⠱Ծ࿡ µû¸¥ ½ºÅà Á¤¸® ¹æ½ÄÀÌ´Ù.
È£Ãâ ±Ô¾à |
ÆĶó¹ÌÅÍ |
½º Åà |
Ư ¡ |
__cdecl |
¿À¸¥ÂÊ --> ¿ÞÂÊ |
È£ÃâÇÑ °÷ |
°¡º¯ ÀÎÀÚ Áö¿ø |
__fastcall |
¿À¸¥ÂÊ --> ¿ÞÂÊ |
È£Ãâ ´çÇÑ °÷ |
ÆĶó¹ÌÅÍ µÎ °³¸¦ ecx, edx¸¦ ÅëÇؼ Àü´ÞÇϱ⠶§¹®¿¡ µÎ °³ ÀÌÇÏÀÇ ÀÎÀÚ¸¦ °¡Áø ÇÔ¼ö¿¡ ´ëÇؼ ºü¸§ |
__stdcall |
¿À¸¥ÂÊ --> ¿ÞÂÊ |
È£Ãâ ´çÇÑ °÷ |
Windows Ç¥ÁØ È£Ãâ ±Ô¾à |
__thiscall |
¿À¸¥ÂÊ --> ¿ÞÂÊ |
È£Ãâ ´çÇÑ °÷ |
ecx¸¦ ÅëÇؼ this Æ÷ÀÎÅ͸¦ Àü´ÞÇÔ |
¸í½ÃÀû ¸µÅ©´Â *.lib ÆÄÀÏ ¾øÀÌ LoadLibrary(), GetProcAddress(), FreeLibrary()¸¦ ÀÌ¿ëÇØ DLLÀ» ·Îµù, ÇÔ¼ö ÁÖ¼Ò±¸ÇÏ¿© ½ÇÇà, DLL ÇØÁ¦¼øÀ¸·Î ½ÇÇàÇÑ´Ù.
Ŭ·¡½ºÀÇ ¸â¹ö ÇÔ¼ö´Â C·Î ÀÛ¼ºµÈ ÇÔ¼ö¿Í´Â ´Þ¸® name manglingÀÌ µÇ±â ¶§¹®¿¡ DUMPBIN À¯Æ¿¸®Æ¼·Î export µÈ ÇÔ¼öÀ̸§À¸·Î GetProcAddress()¸¦ ½ÇÇàÇÑ´Ù.
Ŭ·¡½º ¸â¹ö ÇÔ¼ö ½ÇÇà ¹æ¹ý
Çì´õÆÄÀÏ°ú DLL ÆÄÀϸ¸ ÀÌ¿ëÇØ ¸â¹ö ÇÔ¼ö¸¦ È£ÃâÇÏ´Â ¹æ¹ýÀº ¼¼°¡Áö´Ù.
//ù¹ø° ¹æ¹ý: ¸â¹ö ÇÔ¼ö Sub¸¦ °¡»óÇÔ¼ö·Î ¹Ù²Û´Ù.
pTest->Sub(5);
//µÎ¹ø° ¹æ¹ý
************* __thiscall ¿¹¾à¾î°¡ Àû¿ëµÇ´Â °æ¿ì *****************
int (__thiscall *pSub)(int) = (int (__thiscall *)(int) )GetProcAddress(hInst, "?Sub@CDllServer@@QAEHH@Z");
pSub(pTest, 5);
//¼¼¹ø° ¹æ¹ý (ÇÔ¼ö¸¦ ÅëÇÏ¿© Ŭ·¡½ºÀÇ ÀνºÅϽº Àü´Þ)
int (*pFnSub)(CDllServer*, int) = (int (*)(CDllServer*, int)) GetProcAddress(hInst, "Sub"); //¸í½ÃÀû
pFnSub(pTest, 5);
|
1. ¸â¹ö ÇÔ¼ö ¾Õ¿¡ virtualÀ» ¼±¾ðÇÏ¿© °¡»óÇÔ¼ö·Î ¼±¾ðÇÑ´Ù. °¡»ó ÇÔ¼ö·Î ¼±¾ðÇÒ °æ¿ì Ưº°ÇÏ°Ô ÇØÁÙ ÀÏÀÌ ¾ø´Ù.
2. __thiscallÀ» »ç¿ëÇÏ´Â ¹æ¹ý Ŭ·¡½ºÀÇ ¸â¹ö ÇÔ¼ö´Â __thiscallÀ» »ç¿ëÇÑ´Ù. ÇÏÁö¸¸ .Net 2003¿¡¼ ÀÌ ¿¹¾à¾î´Â Áö¿øµÇÁö ¾Ê´Â´Ù. .Net 2005³ª .Net 2008¿¡¼ Áö¿ø µÇ´ÂÁö´Â À߸𸣰ڴÙ.
CDllServer Ŭ·¡½ºÀÇ Sub ¸â¹ö ÇÔ¼ö ¿øÇüÀº int Sub(int num) ÀÌ´Ù. µÎ±ºµ¥ÀÇ __thiscall È£Ã⠺κÐÀÌ Àִµ¥, º¹ÀâÇØ º¸ÀÌÁö¸¸ ¿øÇü°ú ºñ½ÁÇÏ´Ù. GetProcAddress()ÇÔ¼ö¾ÈÀÇ "?Sub@CDllServer@@QAEHH@Z" À̸§Àº DUMPBIN À¯Æ¿¸®Æ¼³ª ¸µÅ© ¿¡·¯°¡ ¶ß¸é Ãâ·ÂµÈ´Ù.
ÇÔ¼ö ÁÖ¼Ò¸¦ ±¸Çؼ ½ÇÇà ÇÒ ¶§´Â "ÇÔ¼öÁÖ¼Ò( ¿ÀºêÁ§Æ® ÁÖ¼Ò, ÇÔ¼ö·Î ³Ñ±æÀÎÀÚ)" ½ÄÀ¸·Î ¸â¹ö ÇÔ¼ö¸¦ ½ÇÇàÇÑ´Ù.
3. ÇÔ¼ö¸¦ ÅëÇÏ¿© Ŭ·¡½ºÀÇ ÀνºÅϽº Àü´Þ
°¡»ó ÇÔ¼ö¸¦ »ç¿ëÇÏÁö ¾ÊÀ» ¶§, »ç¿ëÇÒ ¼ö ÀÖ´Â ¹æ¹ýÀ¸·Î DLLÀÇ Å¬·¡½º¿¡ Àü¿ªÇÔ¼ö¸¦ ¸¸µé¾î Ŭ·¡½ºÀÇ ¿ÀºêÁ§Æ® ÁÖ¼Ò¿Í ÀÎÀÚ¸¦ ³Ñ±ä´Ù.
extern "C" DLL_DECLSPEC int Sub(CDllServer * pObj, int num)
{
return pObj->Sub(num);
}
|
|
DLL ¸ðµâ¿¡¼ CreateCDllServer()¸¦ ÅëÇØ ¿ÀºêÁ§Æ®¸¦ »ý¼º ÇÏ¿´´Ù¸é, ¿ÀºêÁ§Æ® ÇØÁ¦ÀÇ °æ¿ìµµ DLL¾È¿¡ ¸¸µå´Â °ÍÀÌ ¹Ù¶÷Á÷ÇÏ´Ù.
¿ÀºêÁ§Æ® ÇØÁ¦ ===> fpRelease(pTest)
//DLL ¸ðµâÀÇ ¿ÀºêÁ§Æ® ÇØÁ¦ ÇÔ¼ö
extern "C" DLL_DECLSPEC void ReleaseCDllServer(CDllServer *& pObj)
{
delete pObj;
pObj = NULL;
}
|
C++ÀÌ ³ª¿À±â ÀÌÀü¿¡´Â ÂüÁ¶°¡ ¾ø¾ú±â ¶§¹®¿¡ ÀÌÁß Æ÷ÀÎÅ͸¦ ÀÌ¿ëÇØ ¸µÅ©µå ¸®½ºÆ®¸¦ ±¸Çö Çß¾ú´Ù. ÀÌÁß Æ÷ÀÎÅ͸¦ Æ÷ÀÎÅÍ ÂüÁ¶·Î º¯È¯Çϸé È¥¶õÀÌ ´ú »ý±æ°ÍÀÌ´Ù.
ÂüÁ¶:
Game Programming gems2 Á¤º¸¹®È»ç ¹ø¿ªÆÇ http://www.jiniya.net/lecture/techbox/callconv.html (½Å¿µÁø´ÔÀÇ ÇÔ¼ö È£Ãâ ±Ô¾à)
__declspec(dllimport)À» »ç¿ëÇÏ¿© ÀÀ¿ë ÇÁ·Î±×·¥À¸·Î °¡Á®¿À±â(MSDN)
|