2008/01/25 14:41 [출처] DLLIMPORT / DLLEXPORT|작성자 완전초짜
를 import하거나 export하기 위해 사용합니다.
자세히 말하자면 DLL을 사용하는 프로그램이 DLL로 부터 function등을
가져다 쓰게 하기 위해 외부로 노출(?)시킬 필요가 있는데(.. 이런
함수, 데이터, 개체등을 DLL의 인터페이스라고 하죠..)
이런 목적으로 DLL내의 함수등을 정의할때 dllexport지시자를 붙여 줍니다.
그리고 dllexport를 사용한 함수등에 대해 일반적으로 DLL의 인터페이스를
정의해 두는 DEF파일(Module definition file)에 포함시킬 필요가 없습니다.
반대로 DLL을 가져다 쓰는 프로그램(or 다른 DLL)쪽에선 DLL의 인터페이스
를 사용하기 전에 당연히 미리 선언해 주어야 할 필요가 있습니다. 이때
선언문에서 dllimport 지시자를 함께 사용해 주는 것이죠..
__declspec( dllexport ) int func()
{
return 1;
}
....
__declspec(dllimport) int func() ;
이런 식으로 말이져..
함수의 경우에는 반드시 dllimport를 쓸 필요는 없지만
컴파일러가 좀더 효율적으로 코드를 만들어 주기때문에
함께 써주는 게 좋습니다. 그러나 변수등의 경우에는
꼭 dllimport를 붙여 줘야 함다.
DLL을 통해서 함수를 제공하려면 DLL상의 Export Address Table(PE 포멧)에 함수의 위치를 나타내도록 __declspec(dllexport)지시자를 사용해서 함수를 노출시킨다. 반면에 함수를 호출하는 쪽에서는 특별한 코드 없이 헤더파일(.h)에 포함된 함수 이름을 직접 사용하면 링커가 해당 함수를 호출할 수 있도록 컴파일 시점에 연결시켜준다. 함수를 호출하는 쪽에서 사용한 헤더파일(.h)에 함수 원형이 __declspec(dllimport)으로 정의되지 않았도 정상적으로 DLL에서 제공된 함수를 사용 할 수 있다.
즉 다른 모듈에서 제공되는 함수를 호출하는데 있어서 함수 원형에 __declspec(dllimport)이 선언 유무와는 상관없이 항상 호출할 수 있다. 하지만 결론 부터 말하면 DLL에서 제공되는 함수를 사용할 때에는 항상 함수 선언 앞에 __declspec(dllimport) 지시자를 사용하는 것이 좋다.
위 헤더 파일의 핵심은 모듈을 제공하는 쪽과 사용하는 쪽에서 동일한 하나의 헤더 파일을 공유해서 사용하도록 하는 것이다. (소스 관리 차원에서도 하나의 파일을 유지하는 것이 좋다. 특히 ThirdParty 벤더에서 제공되는 API모듈이라면 더욱더 그렇게 해야한다.)
이렇게 static link용 Lib의 stub에 연결된 경우에도 실행시 실제 DLL의 함수는 정상적으로 호출된다. 그 이유는 DLL 생성시점에 함께 생성되는 Lib 파일의 Stub내부에는 실제 모듈(DLL)의 함수로 점프할 수 있는 코드가 이미 DLL 파일의 컴파일 타임에 이미 생성되어 Stub안에 존재하기 때문에 가능한 것이다. 즉 해당 Stub을 내부 함수처럼 호출하면 그곳에서 실제 모듈(DLL)의 함수를 가르키는 IAT(Import Address Table)를 참조해서 실제 API로 이동하는 코드가 수행되는 것이다.
상기 코드 중에서 당연히 1번의 경우가 훨씬 효과적인 것을 알 수 있다. 2번의 경우에는 JMP를 위한 추가적인 5Byte의 Stub 코드를 더 수행하게 되므로 비효율적이다.
다음과 같은 링크 에러를 보면 실제 함수 이름 앞에 "__imp__" Prefix가 존재하는 것을 알 수 있다.
위의 경우에는 링크 에러가 발생했는데 링크 에러가 발생하지 않으려면 빈 Lib안에 __imp__MyFunc에 대한 Stub이 존재하고 있어야 한다. DLL과 함께 생성된 Lib에는 "MyFunc", "__imp__MyFunc"에 대한 두가지 Stub이 모두 존재하고 있다. 컴파일러는 두 함수 이름을 Lib에 미리 생성해 놓고 있다.
[출처] __declspec(dllimport)의 호출 원리|작성자 iwillhackyou |
'운영체제 & 병렬처리 > DLL_LIB' 카테고리의 다른 글
확장 DLL 전역변수 선언 및 사용 (0) | 2012.11.01 |
---|---|
dllimport과 dllexport (0) | 2012.11.01 |
dll 에서 함수, 변수 읽어오기 GetProcAddress() (0) | 2012.11.01 |
Visual C++ dumpbin.exe 를 이용한 dll(lib) export 내용 알아내기 (0) | 2012.11.01 |
VS2008에서 dll만들기 (0) | 2012.11.01 |