Location | Tag | Media  ||  A | P


[출처] 데브피아

/MD, /MT의 컴파일 옵션의 차이점은 컴파일 시 .obj 파일에 어떤 c runtime library를 삽입 하느냐의 차이입니다.

◆ /MD compile option (multithreaded dll)
    c runtime library(MSVCPRT.LIB)를 컴파일 하는 .cpp파일의 .obj 파일에 삽입하여,
    external symbols와 MSVCP71.dll을 통하여 동적 연결(dinamic link)할 수 있게 하고,
    MSVCPRT.LIB는 MSVCP71.dll을 사용할 수 있도록 구성됩니다.

◆ /MT compile option (multithreaded)
    c runtime library(LIBCPMT.LIB)를 컴파일 하는 .cpp파일의 .obj 파일에 삽입하여,
    external symbols와 정적 연결(static link)를 하게 합니다.

C Run-Time Library를 키워드로 MSDN을 참조해 보십시오.
윗글의 에러메세지는 두가지 종류의 런타임 라이브러리가 링크가 되어 중복 선언되었다는 내용입니다. 

 C Run-Time Library는 standard library를 말합니다.
printf, strcpy, malloc, new, cin, cout 등등이  이 라이브러리에 포함됩니다. 
종류는 꽤 많은데, 별로 복잡하지는 않습니다.

libc.lib : c언어에 해당하는 라이브러리 입니다. printf, strcpy, malloc 등이 구현되어 있습니다.
libcmt.lib : libc 와 동일합니다만, 이것은 멀티쓰레드 용입니다.
msvcrt.lib : libc 와 동일합니다만, 이것은 dll 용입니다.
              ( 위의 두가지는 static link 로 사용되고, 이것은 dynamic link 로 사용됩니다.)
libcp.lib : c++언어에 해당하는 라이브러리 입니다. cin,  cout, new  등이 구현되어 있습니다.
libcpmt.lib : libcp 와 동일합니다만, 이것은 멀티쓰레드 용입니다.
msvcprt.lib : libcp 와 동일합니다만, 이것은 dll 용입니다.
               ( 위의 두가지는 static link 로 사용되고, 이것은 dynamic link 로 사용됩니다.) 

그러므로, 위의 라이브러리는 두개의 그룹중에 하나씩만 포함이 되어야 합니다.
만약, libc 와 msvcrt 가 둘다 링크되면 중복선언 되었다는 에러가 납니다. 

하지만, 다른 프로젝트에서 가지고 왔다면, 이러한 링크옵션 수정하는 것이 쉽지 않을 수 있습니다.
프로젝트 구조를 보아야 알 수 있으나, 한가지 해결방법은....
 

링크에서 메세지에도 나와 있듯이, 링크 옵션에 다음을 추가 하십시오.
/NODEFAULTLIB:library 

library 에 포함시키지 말아야 할 라이브러리를 추가하시면, 이 라이브러리는 링크에 포함되지 않습니다. 

그러면, 중복 선언 에러는 해결 할 수 있습니다.
 

[msdn의 글]
PRB: CRT 라이브러리가 MFC 라이브러리 전에 링크되면 LNK2005 오류가 발생한다
이 문서가 적용되는 제품 보기.
기술 자료 ID : 148652 
마지막 검토 : 2003년 2월 3일 월요일 
수정 : 1.0 
이 페이지에서
현상 원인

해결 방법

해결 방법 1: 링커가 올바른 순서로 라이브러리를 강제 링크하는 방법
해결 방법 2: 문제 모듈을 찾아 해결하는 방법
현재 상태

추가 정보
현상
CRT(C 런타임) 라이브러리와 MFC(Microsoft Foundation Class) 라이브러리가 잘못된 순서로 링크되면 다음과 비슷한 LNK2005 오류가 발생할 수 있습니다. 
nafxcwd.lib(afxmem.obj) : 오류 LNK2005:
"void * __cdecl operator new(unsigned int)"(??2@YAPAXI@Z)이(가)
LIBCMTD.lib(new.obj)에 이미 정의되어 있습니다. 
nafxcwd.lib(afxmem.obj) : 오류 LNK2005:
"void __cdecl operator delete(void *)"(??3@YAXPAX@Z)이(가)
LIBCMTD.lib(dbgnew.obj)에 이미 정의되어 있습니다. 
nafxcwd.lib(afxmem.obj) : 오류 LNK2005:
"void * __cdecl operator new(unsigned int,int,char const *,int)"
(??2@YAPAXIHPBDH@Z)이(가) LIBCMTD.lib(dbgnew.obj)에 이미 정의되어 있습니다. 
mfcs40d.lib(dllmodul.obj): 오류 LNK2005: _DllMain@12이(가)
MSVCRTD.LIB (dllmain.obj)에 이미 정의되어 있습니다. 
mfcs42d.lib(dllmodul.obj): 오류 LNK2005: _DllMain@12이(가)
msvcrtd.lib(dllmain.obj)에 이미 정의되어 있습니다. 
 위로 가기

원인
CRT 라이브러리는 new, delete 및 DllMain 함수에 대해 약한 외부 링크를 사용합니다. MFC 라이브러리에도 new, delete 및 DllMain 함수가 포함되어 있어 CRT 라이브러리 전에 MFC를 링크해야 합니다.

해결 방법
이 문제를 해결할 수 있는 방법에는 두 가지가 있습니다. 첫 번째 해결 방법은 링커가 올바른 순서로 라이브러리를 강제 링크하도록 하는 것입니다. 두 번째 해결 방법은 문제를 일으키는 모듈을 찾아 해결하는 것입니다. 

해결 방법 1: 링커가 올바른 순서로 라이브러리를 강제 링크하는 방법
1. Project 메뉴에서 Settings을 눌러 Project Settings 대화 상자를 엽니다. 
2. Settings For 뷰에서 링크 오류가 발생하는 프로젝트 구성을 선택(강조 표시)합니다. 
3. Link 탭을 누릅니다. 
4. Category 콤보 상자에서 INPUT을 선택합니다. 
5. Ignore Libraries 입력란에 라이브러리 이름(예: Nafxcwd.lib Libcmtd.lib)을 입력합니다.

참고: 링커 명령줄은 /NOD:<library name>과 동일합니다. 
6. Object/library Modules 입력란에 라이브러리 이름을 입력합니다. 이 이름은 반드시 해당 행의 처음 두 라이브러리(예: Nafxcwd.lib Libcmtd.lib)와 같은 순서대로 나열되어야 합니다. 
Visual C++ .NET에서 이 옵션을 설정하려면 온라인 도움말의 Visual C++ 프로젝트 속성 설정 항목을 참조하십시오. 
 위로 가기

해결 방법 2: 문제 모듈을 찾아 해결하는 방법
다음 단계를 수행하여 현재 라이브러리 링크 순서를 확인합니다. 1. Project 메뉴에서 Settings을 눌러 Project Settings 대화 상자를 엽니다. 
2. Settings For 뷰에서 링크 오류가 발생하는 프로젝트 구성을 선택(강조 표시)합니다. 
3. Link 탭을 누릅니다. 
4. Project Options 대화 상자에 다음을 입력합니다.
/verbose:lib 
5. 프로젝트를 다시 빌드합니다. 링크하는 과정에서 출력 창에 라이브러리가 표시됩니다.

현재 상태
이것은 의도적으로 설계된 동작입니다. 

추가 정보
MFC 라이브러리를 사용할 때는 MFC 라이브러리가 CRT 라이브러리 전에 링크되도록 해야 합니다. 이렇게 하려면 프로젝트에 있는 모든 파일이 직접(#include <Afx.h>) 또는 간접(#include <Stdafx.h>)적으로 먼저 Msdev\Mfc\Include\Afx.h를 포함하도록 합니다. Afx.h 포함 파일은 #pragma 주석(lib,"<libname>") 지시어를 사용하여 라이브러리의 순서를 올바르게 조정합니다.

원본 파일 확장명이 .c이거나 파일 확장명이 .cpp이지만 MFC를 사용하지 않는 경우 모듈 맨 위에 작은 헤더 파일(Forcelib.h)을 만들어 포함시킬 수 있습니다. 이 새로운 헤더가 라이브러리 검색 순서를 올바르게 합니다.

Visual C++에는 이 헤더 파일이 들어 있지 않지만 다음 단계를 수행하여 이 파일을 쉽게 만들 수 있습니다. 1. Msdev\Mfc\Include\Afx.h를 엽니다.  
2. #ifndef _AFX_NOFORCE_LIBS와 #endif //!_AFX_NOFORCE_LIBS 사이의 행을 선택합니다.  
3. 선택 영역을 Windows 클립보드로 복사합니다.  
4. 새 텍스트 파일을 만듭니다.  
5. 클립보드 내용을 새 파일에 붙여넣습니다.  
6. 파일을 Msdev\Mfc\Include\Forcelib.h로 저장합니다.

'프로그래밍' 카테고리의 다른 글

vc++ 호출 규약  (0) 2011.03.14
C# C에서 쓰던 typedef 및 #define 사용하기  (0) 2011.03.14
logcat 한글 출력 하는법  (0) 2011.01.26
비주얼스튜디오 단축키  (0) 2010.11.11
선형보간법  (0) 2010.10.28
Posted by Bestend
: