C Standard를 기준으로 설명하였다.

 DLL을 컴파일 할때 소스코드가 길어지고 CPP파일이 많아지고 헤더파일이 많아지면 재정의 오류가 생길수 있다. 
이상하게 헤더 중복 방직 매크로(#pragma once)를 달아놔도 컴파일을 할때 재정의 오류가 나는데 오류메시지는 보통 아래와 같다.


=============================================================================================

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1815): error C2375: 'listen' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(789) : 'listen' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1833): error C2375: 'ntohl' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(793) : 'ntohl' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1850): error C2375: 'ntohs' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(795) : 'ntohs' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1870): error C2375: 'recv' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(797) : 'recv' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1895): error C2375: 'recvfrom' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(803) : 'recvfrom' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1921): error C2375: 'select' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(811) : 'select' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1945): error C2375: 'send' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(818) : 'send' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1970): error C2375: 'sendto' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(824) : 'sendto' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1996): error C2375: 'setsockopt' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(832) : 'setsockopt' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2018): error C2375: 'shutdown' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(839) : 'shutdown' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2039): error C2375: 'socket' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(843) : 'socket' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2063): error C2375: 'gethostbyaddr' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(850) : 'gethostbyaddr' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2083): error C2375: 'gethostbyname' : 재정의.링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(855) : 'gethostbyname' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2101): error C2375: 'gethostname' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(857) : 'gethostname' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2121): error C2375: 'getservbyport' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(861) : 'getservbyport' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2141): error C2375: 'getservbyname' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(865) : 'getservbyname' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2160): error C2375: 'getprotobynumber' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(869) : 'getprotobynumber' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2178): error C2375: 'getprotobyname' : 재정의.링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(871) : 'getprotobyname' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2200): error C2375: 'WSAStartup' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(875) : 'WSAStartup' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2219): error C2375: 'WSACleanup' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(879) : 'WSACleanup' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2236): error C2375: 'WSASetLastError' : 재정의.링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(881) : 'WSASetLastError' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2253): error C2375: 'WSAGetLastError' : 재정의.링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(883) : 'WSAGetLastError' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2270): error C2375: 'WSAIsBlocking' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(885) : 'WSAIsBlocking' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2287): error C2375: 'WSAUnhookBlockingHook' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(887) : 'WSAUnhookBlockingHook' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2304): error C2375: 'WSASetBlockingHook' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(889) : 'WSASetBlockingHook' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2321): error C2375: 'WSACancelBlockingCall' :재정의. 링크가 다릅니다.

=============================================================================================


위의 경우는 winsock2.h 헤더파일이 2번 이상 중복되서 생긴것이다.

각각의 헤더파일이나 CPP에서 해당 헤더파일이 한번만 선언하도록 하고

나머지 #include <winsock2.h>는 주석처리하도록 하면 해결할수 있다.


신고
Posted by 캐스피

 자신이 개발한 프로그램이 다른 컴퓨터에서도 실행하려면 배포관련 컴파일을 해야하는데 대표적으로 

Visual Stduio 2010 프로젝트 속성 -> 정적 라이브러리에서 MFC사용 옵션을 하고 컴파일 했을때 나는 오류인데 메시지는 보통 아래와 같다.

error LNK2001: __imp__wsprintfA 외부 기호를 확인할 수 없습니다.

error LNK2001: __imp__wsprintfA 외부 기호를 확인할 수 없습니다.

error LNK2019: __imp__wvsprintfA@12 외부 기호(참조 위치: "void __cdecl DbgPrintf(char *,...)" (?DbgPrintf@@YAXPADZZ) 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__MessageBoxA@16 외부 기호(참조 위치: "int __cdecl JobPatch(unsigned int)" (?JobPatch@@YAHI@Z) 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__DispatchMessageA@4 외부 기호(참조 위치: _WinMain@16 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__GetMessageA@16 외부 기호(참조 위치: _WinMain@16 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__LoadAcceleratorsA@8 외부 기호(참조 위치: _WinMain@16 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__LoadStringA@16 외부 기호(참조 위치: _WinMain@16 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__RegisterClassExA@4 외부 기호(참조 위치: "unsigned short __cdecl MyRegisterClass(struct HINSTANCE__ *)" (?MyRegisterClass@@YAGPAUHINSTANCE__@@@Z) 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__LoadCursorA@8 외부 기호(참조 위치: "unsigned short __cdecl MyRegisterClass(struct HINSTANCE__ *)" (?MyRegisterClass@@YAGPAUHINSTANCE__@@@Z) 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__LoadIconA@8 외부 기호(참조 위치: "unsigned short __cdecl MyRegisterClass(struct HINSTANCE__ *)" (?MyRegisterClass@@YAGPAUHINSTANCE__@@@Z) 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__UpdateWindow@4 외부 기호(참조 위치: "int __cdecl InitInstance(struct HINSTANCE__ *,int)" (?InitInstance@@YAHPAUHINSTANCE__@@H@Z) 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__ShowWindow@8 외부 기호(참조 위치: "int __cdecl InitInstance(struct HINSTANCE__ *,int)" (?InitInstance@@YAHPAUHINSTANCE__@@H@Z) 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__CreateWindowExA@48 외부 기호(참조 위치: "int __cdecl InitInstance(struct HINSTANCE__ *,int)" (?InitInstance@@YAHPAUHINSTANCE__@@H@Z) 함수)에서 확인하지 못했습니다.


이럴땐 소스코드 맨앞에 해당 함수가 익스포트된 DLL을 전처리 지시자로 선언해주면 해결할수 있다.

예를들면 아래와같다.

#pragma comment(lib,"user32")
#pragma comment(lib,"gdi32")
#pragma comment ( lib , "ws2_32.lib" )
#pragma comment(lib,"Advapi32")


신고
Posted by 캐스피


티스토리 툴바