Visual Studio.NET 2003 환경에서 개발 중에 아주 골때리는 일이 발생하였다.

GetCommConfig 함수를 사용하는 코드였는데,
WindowsXP 에서는 잘 되는데,
Windows2000 의 'Debug' 모드에서만 저 함수가 Error를 return 하는 것이다.(실행이 안되거나 build가 안되는 것도 아니고..)

일단 Debug와 Release의 설정 차이일 것으로 생각되어, 설정을 비교하면서 다른 옵션을 같도록 바꿔 보면서 체크해 봤더니..

구성 속성 -> C++ -> 코드 생성 -> 기본 런타임 검사를 기본값 또는 초기화 되지 않은 변수..로 바꿔 봤더니 제대로 된 값을 return 하는 것이다.
(모두, 또는 스택 프레임..으로 하면 에러 발생)

그래서 MSDN에서 스택 프레임(/RTCs) 관련 내용을 찾아봤더니 다음과 같았다.
영어 해석이 잘 안되어서 내용이 확실치는 않다;;;

스택 frame의 run-time 에러 체킹을 활성화한다.
1) local variable을 nonzero 값으로 초기화한다. 값 초기화와 관련 있는 것 같은데, 어떤 경우에는( 프로그램이 스택 area를 사용한 경우라고 하는데...자세하지 않음) 0으로 초기화되지 않고 이와 관련해서 문제가 생기는 경우가 있다고 하는 것 같다. 그래서 이런 경우의 에러를 찾기 위해서 이렇게 해 주는 것 같다.

2) 배열과 같은 local variable의 overrun이나 underrun을 찾는다. 이 내용은 잘 모르니 pass

3) stack pointer verification을 수행하여 stack pointer corruption을 찾는다. stack pointer corruption은 함수 포인터나 dll 함수 선언 등에서 calling convention을 잘못 썼을 때 발생한다.

뭐 대충 stack 관련 변수/함수를 체킹해 주는 것 같은데, 요 옵션이 먼 영향을 끼치는 건지는 잘 모르겠다.
일단 옵션을 끄고 사용하고, 시간이 되면 변수 초기화 부분을 함 뒤져봐야 겠다.

// TestWaitForSingleObject1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <windows.h>
#include <iostream.h>

HANDLE hEvent;

DWORD WINAPI SampleThread(LPVOID iValue)
{
int iFinish = 10000;
for(int i=100;i<=iFinish;i++)
cout<<i<<endl;

SetEvent(hEvent);
return 0;
}

void main()
{

HANDLE hThread;
DWORD dwGenericThread;
hThread = CreateThread(NULL,0,SampleThread,NULL,0,&dwGenericThread);
if(hThread == NULL)
{

DWORD dwError = GetLastError();
cout<<"SCM:Error in Creating thread"<<dwError<<endl ;
return;

}

hEvent = CreateEvent(NULL,FALSE,FALSE,"Test");

cout<< "Started waiting for the thread to complete.." <<endl ;
//WaitForSingleObject(hEvent,INFINITE);
WaitForSingleObject(hEvent,100);
cout<<"Thread Completed."<<endl ;

if(hEvent != INVALID_HANDLE_VALUE)
CloseHandle(hEvent);

}

WaitForSingleObject의 2번째 인자를 바꾸어 보면 조금씩 다른 결과가 나온다..
가끔은 에러도 나는데;;; 이유는 잘 모르겠다


http://www.free2code.net/plugins/forums/view.php?f=3&p=47553

계속 link 시에 "C:\Program.obj 를 찾을 수 없다" 는 에러가 나서 번민하던 중..
구글에서 Program.obj로 검색해 봤더니 위와 같은 글이 나오더라..

나와 똑같은 문제였는데...
간단히 요약하면,
(VS.NET 기준으로)프로젝트 -> 속성 -> 링커 -> 입력 -> 추가 종속성 항목에서 "C:\Program files\어쩌구저쩌고.." 를 입력할 때에 큰 따옴표를 넣지 않았더니

C:\Program
Files
Microsoft
Platform
SDK
...

이런 식으로 인식하고 있더라 -_-a

설정창에는 큰따옴표를 넣읍시다!!

윈도우즈 프로그래머로 회귀한지 만 1주 -_-;

SHCreateDirectory 를 이해할 수 없다는 에러메시지가 계속 디벼져서 이거때문에 이틀을 홀랑 날려먹고
구글검색하다가 발견한 한 글에 영감을 얻어서, ShlObj.h 를 보게 되었다.

역시나 문제는 요놈 때문이었다.

#if (_WIN32_IE >= 0x0601)
SHSTDAPI_(int) SHCreateDirectory(HWND hwnd, LPCWSTR pszPath);
#endif  // (_WIN32_IE >= 0x0601)

MSDN에 보면
IE 6.0의 경우 Minimum system required로...
_WIN32_IE>=0x0600 를 써야 하는데..

Platform SDK를 Windows 2003 용을 써서 그런지...
_WIN32_IE>=0x0601로 걸려 있어서 이것 때문에 코드가 인식을 못하고 있는 것 같다.
(참고로, 프로젝트에는 _WIN32_IE는 선언되어 있지 않았다)

그래서 걍 Platform SDK를 VS.NET 에서 기본적으로 깔려 있는 것으로 바꿔 놓았다.
(기본적으로 깔려 있는 Platform SDK에는 define이 걸려 있지 않고 걍 선언만 되어 있음!)

역시 마이크로소프트 프로그래밍은 문서를 디벼 파아 한다는 사실을 깨달았다...

참고로 _WIN32_WINNT, _WIN32_WINDOWS 를 각 소스 코드 or 프로젝트 환경에 define 하여서 minimum system required를 정의할 수 있다! 자세한 것은 MSDN 문서 참고!

http://blog.naver.com/neokimy2k?Redirect=Log&logNo=20008310584

http://kin.naver.com/db/detail.php?d1id=1&dir_id=10104&eid=DZ7R1wNiaEIvvIXwjmo7QeIx0ISxQH/L

http://blog.naver.com/rgba?Redirect=Log&logNo=6344207

Line style 관련 상수 모음
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20269010.html

Color Index
http://www.mvps.org/dmcritchie/excel/colors.htm

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/basic_17.asp
http://www.devx.com/tips/Tip/12527

위의것은 MSDN의 extern 키워드에 대한 설명
밑의것은 extern "c" 에 대한 설명임...

http://blog.naver.com/hecate12?Redirect=Log&logNo=40019435414

출처 : MSDN(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/lnk2001.asp)

Linker Tools Error LNK2001
unresolved external symbol "symbol"


Code will generate this error message if it references something (like a function, variable, or label) that the linker can’t find in all the libraries and object files it searches. In general, there are two reasons this error occurs: what the code asks for doesn’t exist (the symbol is spelled incorrectly or uses the wrong case, for example), or the code asks for the wrong thing (you are using mixed versions of the libraries?some from one version of the product, others from another version).

Numerous kinds of coding and build errors can cause LNK2001. Several specific causes are listed below, and some have links to more detailed explanations.

Coding Problems

Mismatched case in your code or module-definition (.DEF) file can cause LNK2001. For example, if you named a variable “var1” in one C++ source file and tried to access it as “VAR1” in another, you would receive this error. The solution is to exactly match the case of the symbol in all references.


A project that uses function inlining yet defines the functions in a .CPP file rather than in the header file can cause LNK2001.


If you are using C++, make sure to use extern “C” when calling a C function from a C++ program. By using extern “C” you force the use of the C naming convention. Be aware of compiler switches like /Tp or /Tc that force a file to be compiled as a C (/Tc) or C++ (/Tp) file no matter what the filename extension, or you may get different function names than you expect.


Attempting to reference functions or data that don't have external linkage causes LNK2001. In C++, inline functions and const data have internal linkage unless explicitly specified as extern.


A missing function body or variable will cause LNK2001. Having just a function prototype or extern declaration will allow the compiler to continue without error, but the linker will not be able to resolve your call to an address or reference to a variable because there is no function code or variable space reserved.


Name decoration incorporates the parameters of a function into the final decorated function name. Calling a function with parameter types that do not match those in the function declaration may cause LNK2001.


Incorrectly included prototypes will cause the compiler to expect a function body that is not provided. If you have both a class and non-class implementation of a function F, beware of C++ scope-resolution rules.


When using C++, make sure that you include the implementation of a specific function for a class and not just a prototype in the class definition.


Attempting to call a pure virtual function from the constructor or destructor of an abstract base class will cause LNK2001 since by definition a pure virtual function has no base class implementation.


Only global functions and variables are public.
Functions declared with the static modifier by definition have file scope. Static variables have the same limitation. Trying to access any static variables from outside of the file in which they are declared can result in a compile error or LNK2001.

A variable declared within a function (a local variable) can only be used within the scope of that function.

C++ global constants have static linkage. This is different than C. If you try to use a global constant in C++ in multiple files you get error LNK2001. One alternative is to include the const initializations in a header file and include that header in your .CPP files when necessary, just as if it was a function prototype. Another alternative is to make the variable non-constant and use a constant reference when assessing it.

Compiling and Linking Problems

The names of the Microsoft run-time and MFC libraries needed at link time are included in the object file module by the Microsoft compiler. If you use the /NOD (/NODEFAULTLIB) option, these libraries will not be linked into the project unless you have explicitly included them. Using /NOD will cause error LNK2001 in this case.


If you are using Unicode and MFC, you will get an unresolved external on _WinMain@16 if you don’t create an entrypoint to wWinMainCRTStartup. Use the /ENTRY option or type this value in the Project Settings dialog box. (To find this option in the development environment, click Settings on the Project menu, then click the Link tab, and click Output in the Category box.) See Unicode Programming Summary.

See the following Knowledge Base articles located in the Online Information System for more information. An easy way to reach an article is to copy a "Q" number above, open the Search dialog box from the Help menu and select the Query tab, then paste the number into the first text box and press ENTER.
Q125750 "PRB: Error LNK2001: '_WinMain@16': Unresolved External Symbol"


Q131204 "PRB: Wrong Project Selection Causes LNK2001 on _WinMain@16"


Q100639 "Unicode Support in the Microsoft Foundation Class Library"
Linking code compiled with /MT with the library LIBC.LIB causes LNK2001 on _beginthread, _beginthreadex, _endthread, and _endthreadex.


When compiling with /MD, a reference to "func" in your source becomes a reference "__imp__func" in the object since all the run-time is now held within a DLL. If you try to link with the static libraries LIBC.LIB or LIBCMT.LIB, you will get LNK2001 on __imp__func. If you try to link with MSVCxx.LIB when compiling without /MD you will not always get LNK2001, but you will likely have other problems.


Linking code compiled with an explicit or implicit /ML to the LIBCMT.LIB causes LNK2001 on _errno.


Linking with the release mode libraries when building a debug version of an application can cause LNK2001. Similarly, using an /Mxd option (/MLd, /MTd, or /MDd) and/or defining _DEBUG and then linking with the release libraries will give you potential unresolved externals (among other problems). Linking a release mode build with the debug libraries will also cause similar problems.


Mixing versions of Microsoft libraries and compiler products can be problematic. A new compiler version's libraries may contain new symbols that cannot be found in the libraries included with previous versions. Use DUMPBIN to find out if a symbol is in a 32-bit object file or library.


There is currently no standard for C++ naming between compiler vendors or even between different versions of a compiler. Therefore linking object files compiled with other compilers may not produce the same naming scheme and thus cause error LNK2001.


Mixing inline and non-inline compile options on different modules can cause LNK2001. If a C++ library is created with function inlining turned on (/Ob1 or /Ob2) but the corresponding header file describing the functions has inlining turned off (no inline keyword), you will get this error. To prevent this problem, have the inline functions defined with inline in the header file you are going to include in other files.


If you are using the #pragma inline_depth compiler directive, make sure you have a value of 2 or greater set, and make sure you are using the /Ob1 or /Ob2 compiler option.


Omitting the LINK option /NOENTRY when creating a resource-only DLL will cause LNK2001.


Using incorrect /SUBSYSTEM or /ENTRY settings can cause LNK2001. For example, if you write a character-based application (a console application) and specify /SUBSYSTEM:WINDOWS, you will get an unresolved external for WinMain. For more information on these options and entry points, see the /SUBSYSTEM and /ENTRY linker options.

Export Problems

When you are porting an application from 16 to 32 bits, LNK2001 can occur. The current 32-bit module-definition (.DEF) file syntax requires that __cdecl, __stdcall, and __fastcall functions be listed in the EXPORTS section without underscores (undecorated). This differs from the 16-bit syntax, where they must be listed with underscores (decorated). For more information, see the description of the EXPORTS section of module-definition files.


Any export listed in the .DEF file and not found will cause LNK2001. This could be because it does not exist, is spelled incorrectly, or uses decorated names (.DEF files do not take decorated names).
This error message is followed by fatal error LNK1120.

The following sections give more detailed information on some of the issues named in the above list.

출처 : 데브피아(http://www.devpia.co.kr)

LNK2001 에러는 사용하시려는 라이브러리가 함께 링크되지 않아서,
참조할 라이브러리를 링커가 찾지 못하기 때문에 나는 에러입니다.

저 같은 경우에는요 라이브러리나 함수, 변수를 호출하는데 실제 정의된 파일이 없을때 자주 경험 했습니다.

링크오류나는 부분이 프로젝트에 포함되어있는지 확인해주세요.

그냥 제가 경험한 부분만 적어 보았구요 ! 다른 이유일 수 있겠네요

참조만 해주시구요 ! 행복하세요 !