[헤더화일에]ifdef 와 define에서 문의드립니다.
글쓴이: shean0 / 작성시간: 수, 2003/07/02 - 5:27오후
현재 dll을 링크한 프로그램을 다운받았습니다.
그런데 ..dll 용량이 크고..다운받은 프로그램소스가 커서.. 필요부분만 발췌하려구 하는데요..
이 상황에서..... 문의를 드립니다.
아래 소스를 가지고 기본적인 질문과...
tip을 문의 드립니다.
#if defined (__BEOS__) # if defined (ZLIB_DLL) # define ZEXTERN extern __declspec(dllexport) # else # define ZEXTERN extern __declspec(dllimport) # endif #endif #ifndef ZEXTERN # define ZEXTERN extern #endif ZEXTERN const char * ZEXPORT zlibVersion OF((void));
이문장의 해석을 부탁드립니다
제가 해석할수 있는 부분까지는
ifdef __BEOS__ 이것이 define되어 있으면... 이렇게는 해석할 수 있는데요.
문제는 #define ZEXTERN extern __declspec(dllexport) ------------------------------------ 문장의 해석이 안되구요# define ZEXTERN extern
-------- 여기에 extern이면
ZEXTERN const char * ZEXPORT zlibVersion OF((void));
-->extern const ... 이것일 것이죠..
그리고 여기서 # define const[enter] 이런 문장은 const를 없는것처럼 무시하라는 것인가요?
또한.. 지금 보고 있는 소스에 dll을 link하고 #ifdef ..가 상당히 복잡하게 나와 있는데요.. 여기서 어떤 ifdef문이 사용되는지 알수 있는 방법은 없나요... 즉 dll 화일을 제거하고..소스를 다시 컴파일 하려구 하거든요. 물론 dll화일에 있는 정보를 다시 소스에 셋팅하려구요... 흠 방법이 없을까요??
한개만 더요...#ifdef __cplusplus extern "C" { #endif 여기서 extern "C"의 의미가 뭐인지요? 제가 알고 있기로는 여기 말고 다른 화일.c 로 된 부분을 extren으로 가져온다... 음..맞는지요?
Forums:
[하양] 얌...
#define const
이 부분은 const declarator를 무시 하게 되네요...
제가 해보니...
그리고 #ifdef 가 어디서 사용되었는지는...
각 #ifdef 부분에 printf문을 넣어서 찍어 보시는게 나으실거 같네요...
<어떠한 역경에도 굴하지 않는 '하양 지훈'>
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
네 문제는 헤더화일부분의 해석때문에
네..
문제는 헤더화일이라는 것에 문제가 있습니다.
음..조금만 더 힌트를 주세요.
언제나 즐프를 꿈꾸며~
임의의 파일을 만들어서 테스트해 보세요.
아래와 같은 임의의 파일을 만들어서 테스트해 보세요.
cpp 를 이용해서 전처리된 소스 파일을 보시면 될 겁니다.
물론 양이 많을 수도 있지만 확실한 방법이죠.
너 행복하니?
[하양] 그렇다면...
전처리가 head file에 있다면...
어쩔 수 없이...
본문 main()에서 이 선언 문 부분을 테스트용으로 넣어서 찍어 보는 수밖에 없지 않을까 생각이 드네요...
main() 안에 다시 #ifdef, #endif 부분을 넣고 찍어 보시길...
다른 뭐... 뽀족한 수는... 글쎄요...-_-ㅋ
<어떠한 역경에도 굴하지 않는 '하양 지훈'>
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
Re: [헤더화일에]ifdef 와 define에서 문의드립니다.
우선, __BEOS__, ZLIB_DLL, __declspec(dllexport), __declspec(dllimport)
의 의미를 알아내셔야 합니다 - 이는 직접 관련된 메뉴얼 등을 살펴보셔야
합니다.
제 추측에 따르면, BeOS 에서는 표준 C 언어가 기본적으로 제공하는
internal/exteranl linkage 외에 DLL 을 위해 특별한 linkage 를 제공하는
것 같습니다. 이에 따라 ZLIB_DLL 이 정의되어 있는지 여부에 의존해 프로
그램 소스 상에 external linkage 로 선언되어 있는 대상체나 함수를 다르
게 다루도록 하려는 의도 같습니다.
아랫 부분의 (한줄 떨어져 있는) #ifndef 는 그 위의 과정에서 어떠한 경우
에도 해당되지 않아 ZEXTERN 이 매크로로 정의되지 않은 경우를 다루기 위
한 것입니다. 위의 잘려나간 예만을 놓고 생각한다면 사실상
#if !defined(__BEOS__)
와 다르지 않습니다만, 그 윗부분에 ZEXTERN 을 다른 내용을 정의하는 또
다른 #if 지시자가 있을 것이라 생각합니다.
언어의 keyword 를 매크로로 정의할 수 있도록 해주는 경우 얻을 수 있는
주요한 장점입니다. 말씀하신대로 프로그램 내에 사용된 const 를 제거할
때 사용하는 것이며, const 를 지원하지 않는 구식 환경을 위해 그와 같은
매크로 정의를 써주는 것이 보통이지만, const 로 선언된 대상체를 다소 특
별하게 다루는 implementation 에서 원하는 프로그램의 행동을 얻기 위해
사용할 가능성도 배제할 수는 없습니다.
다른 분들이 말씀하신 것처럼 해당 프로그램의 번역을 전처리 단계까지만
진행해보는 방법이 있습니다. 아니면, 작업 환경이 scpp (selective C
Preprocessor) 같은 tool 을 제공한다면 다른 전처리기 지시자는 처리하지
않고 conditional translation 을 위한 부분만 처리해서 살펴보는 것도 도
움이 되리라 생각합니다.
C++ 프로그램에서 C 프로그램으로 번역된 함수를 사용하기 위해 선언된 함
수의 linkage 를 "C" linkage 로 만들어 주는 것입니다. 예를 들어, C++ 프
로그램은 overloading 지원을 위해 name mangling 등의 방법을 사용하지만,
C 는 그렇지 않기에 C++ 에서 그러한 영향을 고려하지 않고 C 함수를 호출
하기 위해서는 C 프로그램으로 번역된 것임을 알릴 필요가 있겠지요.
그럼, 조금이라도 도움이 되었기를 바랍니다.
--
Jun, Woong (woong at gmail.com)
http://www.woong.org
Re: [헤더화일에]ifdef 와 define에서 문의드립니다.
지금 보고있는 소스가 vc++로 짜여진 것인데요..
이것을 unix로 바꾸고 있는것이거든요..
window 에서 혹시 vc++에서는 dll을 볼수가 있지 않나요..
그리고 scpp를 찿고 있는데...네트웨크쪽으로만 검색이 되네요..쩝.
제가 잘 몰라서 .. 조금 더 조언을 부탁드립니다.
찿고로..아래와같은 헤더를 맞출려구 하거든요.
언제나 즐프를 꿈꾸며~
Re: [헤더화일에]ifdef 와 define에서 문의드립니다.
MS-Windows 라... 죄송하지만, MS-Windows 에 대해서는 제가 도와드릴 수
있는 부분이 거의 없습니다. 아래 인용하신 소스 중에서 VC/C++ 이나
Borland 사 제품과 관련된 부분은 해당 implementation 을 다루는 게시판이
나 뉴스그룹을 이용하시는 것이 더 빠른 답변을 얻을 수 있는 길이 아닐까
생각합니다.
"selective C preprocessor" 를 검색해 보시기 바랍니다 - Windows 에서 실
행시킬 수 있는 것으로는 다음이 있네요.
http://hp.vector.co.jp/authors/VA010446/toolbox1/#scpp
말씀드린대로 scpp 는 conditional compilation 과 관련된 지시자만을 확장
해 줍니다. 즉, #define ZEXPORT WINAPT 같은 일반적인 매크로의 확장은 수
행해주지 않습니다 - 이것이 일반 preprocessor 와 "selective"
preprocessor 의 차이입니다. 이는 conditional compilation 에 관여하는
특정 매크로가 적절히 정의되었을 경우 어떠한 구조가 선택적으로 번역되는
지를 확인할 때 유용한 tool 이며, 특정 환경에 필요한 매크로 정의를 내재
하고 있지 않기에 직접 옵션을 통해 제공해주실 필요가 있습니다. 하지만,
프로그램을 분석하는 목적과 아래 인용해주신 구조를 볼 때 굳이 scpp 가
필요한 상황은 아닌듯 합니다.
말씀하신 환경에 근본적으로 익숙하지 않기에 아래 인용하신 구조에 대해
제가 충분한 답변을 드리기는 어려울 것 같습니다. 하지만, "추측" 과 조언
을 드리자면, 지금 이 프로그램은 주어진 환경에 따라 적절히 DLL 이 생성
될 수 있도록 하기 위해 매크로를 사용하고 있습니다. 따라서, 이와 같은
구조를 굳이 모두 이해하실 필요 없이 가장 이해하기 쉬운 환경을 선택하여
해당 환경에서 프로그램이 사용하는 (Z 으로 시작하는) 각 매크로가 어떠한
의미를 갖는지 아는 것이 중요합니다. 어차피 UNIX 로 포팅할 계획이시라면
그 의미만을 분명히 파악하신 후에 UNIX 환경에서 동등한 의미로 해당 매크
로를 정의만 해주면 됩니다 - 물론, 분명 추가적인 다른 문제가 있을 것이
라 믿어 의심치 않습니다만... --;
#if defined(ZLIB_DLL)
라이브러리에서 DLL 로 번역될 소스에만 이하의 내용을 적용한다는 의도 같
습니다 - ZLIB_DLL 은 해당 프로그램에서 정의되고 사용되는 것이므로 함께
배포된 문서가 있다면 분명 이를 설명할 것입니다.
이상의 부분은 VC/C++ 에서 DLL 을 생성하기 위해 적절히 매크로를 정의하
는 것 같습니다. VC/C++ 이 제공하는 기정의 매크로의 의미가 (제 사견으로
는) 더럽게 애매모호하기 때문에 저라면 아래를 선택하겠습니다. (혹시라도
VC/C++ 에 익숙한 분이 계신다면 이 부분을 설명해주시지 않을까 생각합니
다)
# if defined (__BORLANDC__)
Borland 사의 다른 제품이라면 __BORLANDC__ 가 정의되어 있는 것으로 알고
있습니다. 따라서, 아래 내용은 우선 Borland 사의 제품 (C++Builder 포함)
에 해당되는 것입니다.
# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
이 프로그램이 target 으로 삼은 Borland 사 제품이 __BORLANDC__ >=
0x0500 의 조건을 만족하고 WIN32 환경이면 이하의 내용이 적용됩니다 -
__declspec() 와 WINAPI, WINAPIV 를 지원하는 환경에 해당하는 조건인 듯
합니다. 참고로 제가 기억하고 있는 바로는 C++ Builder 5 에서 해당 매크
로는 0x0550 으로 정의되어 있습니다.
위에서 말씀드린 조건을 만족하는 Borland 사의 제품을 설치하신 후에
(On-line 메뉴얼이 제공되는지는 모르겠습니다만) Help 나 메뉴얼을 찾아보
시면 __declspec 과 WINAPI, WINAPIV 에 대한 설명을 찾을 수 있습니다. 만
약 그 의미를 알아내 동등한 의도의 UNIX 환경에서의 표현을 찾아낸다면 아
래 부분 (혹은 그 외에 존재할지 모르는 유사한 형태의 다른 조건부 번역
구조) 은 분석할 필요가 없습니다.
일단, 보여주신 구조만 가지고 제가 할 수 있는 모든 추측을 동원하여 도움
을 드리고자 노력했습니다. MS-Windows 에서의 프로그래밍은 제가 거의 알
지 못하는 부분이기에 더 자세한 답변 드리기는 어려울 듯 합니다. 해당 환
경에 익숙하신 다른 분들께서 잘못된 부분에 대한 지적이나 추가 설명 해주
시리라 믿습니다.
그럼...
--
Jun, Woong (woong at gmail.com)
http://www.woong.org
declspec...
VC++에서 __declspec(dllimport)와 __declspec(dllexport)는
각각 해당 펑션을 DLL에서 import할 것인지, export할것인지를 의미합니다.
__declspec(dllimport) int func(void); ... 와 같이 선언되면
해당 DLL의 Lib에서 'func'펑션을 static으로 읽어서 링크하라는 의미가되고,
즉, 외부의 DLL에서 함수를 읽어서 링크할 때 쓰이고,
__declspec(dllexport) int func(void); ... 와 같이 선언되면
'func'라는 펑션을 dll에 export하라는 의미로 DLL바이너리를 만들때 주로 쓰입니다.
이들은 둘다 Dynamic 링크가 아니고 Static 링크로 동작하게 됩니다.
그럼 이만.
Re: declspec...
VC++ 에도 __declspec() 이 제공되나요? BCB 에서 해당 기술을 사용한 것을
보았습니다. 구체적으로 __declspec() 의 정체가 무엇인지 궁금합니다. 서로
다른 implementation 이 단지 공통적인 기술을 지원하는 것인지요?
--
Jun, Woong (woong at gmail.com)
http://www.woong.org
Re: declspec...
김희상님께서 쓰신,
"__declspec(dllimport) int func(void); ... 와 같이 선언되면
해당 DLL의 Lib에서 'func'펑션을 static으로 읽어서 링크하라는 의미가되고,"
만일 "여기서 static 으로 읽어서 링크" 가 정말 static 라이브러리처럼, 실행
파일에 함수 자체가 링크되는 것을 의미하신 것이라면, 잘 못 알고 계신겁니다.
그냥 DLL 안에 있는 함수 프로토타입을 나타낸 것으로, vc++ 에서는
함수에 대해서는, dllimport 는 써도 되고 안써도 됩니다.
단, 전역 변수나, C++ 클래스를 import 할 때는 dllimport 써야 합니다.
윈도우즈는 DLL 함수를 export 하기 위해 두가지 방법을 이용할 수
있는데, 한가지는 export 에 상응하는 키워드를 사용하는 것이고, 다른 하나는
def 파일을 사용하는 것입니다.
export 키워드는 컴파일러마다 약간씩 다른데, 볼랜드 컴파일러는
_export, __export 등을 써왔습니다. VC++ 에서는 __declspec 을
쓰구요. MS 제품이 그렇게 쓰다보니, 다른 윈도우즈용 컴파일러도 그
키워드를 대체로 따르게 되는 것 같네요.
반면, UNIX 공유 라이브러리는 대개 윈도우즈 DLL 처럼 export, import
따질 일이 없죠.
Orion Project : http://orionids.org
Re: declspec...
잘못알아들으셨군요.
제가 말한 Static이라는말은, 코드자체야 DLL에 따로 있지만 프로그램 실행시 초기에 자동(??.. DelayedLoad같은 기법이 있긴 하지만 열외로 하고..)으로 DLL이 뜬다는 얘기였습니다. 별도의 DLL을 읽으라는 명령어가 없어도 말이죠.... 그러기 위해서 필요한게 DLL에서 Import Lib를 만들어서 같이 "링크"를 시키면 다른 일반 함수처럼 쓸수 있다는 뜻이고요....
이에반대되는 Dynamic은 LoadLibrary, FreeLibrary처럼 실제 DLL을 읽어들이라는 명령어를 통해 모듈을 읽어들이고, GetProcAddress을 통해 원하는 함수 주소를 알아내서 실행하는 방법을 뜻한다...는 말이었습니다.
Static이 코드자체가 들어간다는 뜻은 아니었습니다.....
쓴김에 좀 더........
위에서 말한 Dynamic 방법..즉, LoadLibrary, FreeLibrary, GetProcAddress등을 통해 함수를 찾아서 호출하는 방법은 DLL에서 함수 한두개 찾아서 실행할때는 별문제 안되지만, 수십~수백개의 함수를 찾아야된다면 여간 불편한게아닙니다. 뭐, 그래서 안되는 것도 아니고 좀 노가다일 뿐(?)이지만...
그래서 보통은 위에서 말한 Import Lib를 통한 Static 방법을 많이 쓰는데...우선 편하니깐.... :lol: ...하지만 덩치큰 모듈들이 여러개 있을경우 DLL의 의미가 상당히 퇴색해버리죠...그래서 나온게 Delayed Load입니다. 이내용은 주제를 벗어나는 것같으니깐 더이상 언급하지 않겠습니다.
채스맨님께서 말씀하신것처럼 DLL에 함수를 내보내는방법은 __declspec(dllexport)를 써도 되지만 .def파일을 쓰는게 윈도우에선 전통(?)적인 방법이었죠...컴파일러 회사를 그리 가리지도 않았고.....
.def파일을 사용하지 않고 export할때의 단점은 이름 생성규칙에 조심하여야됩니다. 'func'라는 이름으로 나가지 않고 '울랄랄func울랄랄'같은 형태로 나갑니다. - 물론, 컴파일러나 c/c++, 호출규칙등에 따라 다릅니다. '울랄랄'같은게 붙지 않을 수도 있고...보통의 경우를 얘기하는겁니다. :o -
.def파일을 쓰면 하나 장점이, export 함수의 ordering 번호를 지정할 수도 있고 남에게 보이기 싫은 함수들은 이름을 감출수도 있다는 장점이 있죠.. :D
게다가 위의 이름생성규칙같은거 신경쓸 필요도 없고~~
(물론 만들때와 쓸때의 호출규칙에 신경쓰지 않아도 된다는 뜻은 아닙니다~)
그럼 모두 즐거운 하루를~~
댓글 달기