정리

[펌] MFC 헤더와 라이브러리 설명

저장소/VC++

[출처] MFC 모든 헤더와 라이브러리 설명 [2]|작성자 헤이즐넛


다음글은 하이텔  MFC소모임의 시삽이신 권정혁님의 글을 정혁님의 허락하에
다음과 같이 기재합니다. 허락해주신 정혁님께 감사드립니다.
****************************************************************************

이 글은 Mike Blaszczak 의 책 "Professional MFC" 의 Appendix D 에 들어있는
내용을 번역한 글입니다. 제 허락없이는 다른 어떤게시판에도 옮기실수 없습니
다. 물론 글의 원 소유자는 Mike 입니다.

                                            MFC&T 사용자 모임 시삽 권정혁

============================================================================
MFC 헤더와 라이브러리 설명 (The Foundation Classes Headers and Libraries) #2

2. 런타임 라이브러리 (Run-time Libraries)

이 테이블은 Visual C++ 과 함께 제공되는 라이브러리와 Pre-Compiled Object 들의 
기능에 대한 짧은 설명을 보여줍니다.

------------------------------------------------------------------------------
런타임 라이브러리 (Run-time Libraries)
------------------------------------------------------------------------------

파일설명

Advapi32.lib  레지스트리나 보안 관련 API 같은 진보된 API 서비스 들에 대한 
              임포트 라이브러리 입니다. 이 임포트 라이브러리와 링크하는 것은
              당신의 프로그램에서 Advapi32.dll에 포함된 함수들을 사용가능하게
              합니다.

Atl.lib       MS의 Active Template Library에 대한 라이브러리입니다.

Binmode.obj   이 모듈과 링크하면 C 런타임 라이브러리에 의해 오픈되는 화일들이
              기본적으로 Binary 모드로 열리도록 만듭니다.

Cap.lib       Call Attributed Profiler 에 대한 인터페이스 입니다. 
              이 툴은 함수 호출 패턴(Function Call Patterns)을 분석함으로써 
              Win32 어플리케이션을 튜닝하게 해줍니다.

Chkstk.obj    런타임용 Stak-Depth 체킹 모듈입니다. 
              이 모듈은 모든 함수 호출전에 스택의 크기(Depth)를 체크함으로써 
              Stack Overflow 가 났는지 체크하는 것을 도와줍니다. 
              Windows NT 에서는 프로그램의 스택 세그먼트를 조심스레 체크하며,
              스택 오버플로우가 난다면 프로그램을 깨끗히 종료시켜주므로 
              이 파일은 거의 필요가 없습니다. 

Comctl32.lib  윈도우 공용 컨트롤(Windows common controls)에 대한 라이브러리 
              입니다.

Comdlg32.lib  윈도우 공용 대화상자(Windows common dialogs)에 대한 라이브러리
              입니다. 이 라이브러리는 표준 화일오픈,화일저장,폰트선택,프린트
              ,컬러 선택 다이얼로그에 대한 인터페이스를 제공합니다.

Commode.obj   전역적인 File Commit Flag 값을 Commit 으로 설정합니다. 
              이 파일과 링크하는것은 오픈되는 모든화일이 기본적으로 Commit 
              모드에서 열리도록 합니다.

Compmgr.lib   컴포넌트에대한 임포트 라이브러리입니다.

Ctl3d32.lib   3차원(Three-D) 컨트롤에대한 지원 라이브러리입니다. 
              이 라이브러리는 다이알로그와 컨트롤이 3차원으로 보이도록 합니다.
              이 파일은 거의 안쓰입니다. 단지 이전버젼과의 호환을 위해 
              제공됩니다.

Ctl3d32s.lib  Win32s 용 프로그램에대한 Ctl3d 라이브러리 입니다.

D3drm.lib     Direct3D 렌더링 모델(Rendering Model) API에 대한 
              라이브러리입니다.

Daouuid.lib   DAO 객체들에 대한 UUID 값을 가지고 있는 라이브러리입니다.

Ddraw.lib     DirectDraw API용 라이브러리입니다.

Dflayout.lib  Compound Document File(복합문서파일)에 대한 저장소 관리
              (Storage Management)를 하는 OLE 함수들에 대한 임포트 
              라이브러리입니다.

Dlcapi.lib    DLC 3270 연결을 위한 라이브러리 입니다.

Dplay.lib     DirectPlay API용 라이브러리 입니다.

Dsound.lib    DirectSound API용 라이브러리입니다.

Fp10.obj      이 모듈과 링크하는것은 프로그램이 기본적으로 53비트 대신 64비트
              부동소수점(Floating-Point Precision) 형식으로 알고리즘을 
              사용하게 합니다.

Gdi32.lib     Windows GDI 임포트 라이브러리 입니다. 이 라이브러리와 링크하는
              것은 프로그램이 Windows 의 Graphic Device Interface 에 있는 
              SelectObject(),CreateFont(),LineTo() 와 같은 루틴을 호출하여 
              디스플레이나 프린터에 그리기를 수행할수 있도록 합니다. 

Glaux.lib     OpenGL 보조 함수 라이브러리 입니다. 거의 모든 프로그램에서 
              사용되지 않으나, 이것은 OpenGL의 핵심(Core) 라이브러리의 기능을
              향상시키도록 합니다. Opengl32.lib도 참조하십시오.

Glu32.lib     OpenGL 그래픽의 핵심 함수 라이브러리 입니다. 
              Opengl32.lib도 참조하십시오.

Hlink.lib     IHlink 와 관련 인터페이스 지원용 라이브러리 입니다. 
              이 인터페이스들은 ActiveX 객체가 일반적인 하이퍼링크 스타일
              (Hyperlink-Style)의 이동을 구현하는것을 도와줍니다.

Imagehlp.lib  디버거 같은 시스템 툴들이 다른 프로세스를 관리하고 디버그 
              정보를 추출하도록 하는 루틴이 들어있는 라이브러리 입니다.

Imm32.lib     Input Method Editor(IME)의 사용에 라이브러리입니다. 
              IME는 조그만 팝업윈도우창으로 보이며,다른나라 글자를 선택하도록
              해줍니다. (한글윈도우 사용자는 다들 아시죠..? )

Kernel32.lib  Windows Kernel 의 임포트 라이브러리입니다. 이 라이브러리와 
              링크함으로써 Windows kernel 안에 들어있는 루틴의 호출이 가능해 
              집니다. Windows Kernel 에는 CreateSemaphore() 나 GlobalAlloc()
              같은 함수들이 포함되어 있습니다.

Largeint.lib  수학계산용 Large Interger지원 라이브러리입니다. 이 라이브러리는
              단지 호환목적으로 제공됩니다. Visual C++ 의 컴파일러는 
              기본적으로 64Bit Integer 를 지원합니다.

Libc.lib      표준 C Runtime 라이브러리입니다. 이 라이브러리는 sprintf() 나 
              strcpy() 같은 함수들이 포함되며,프로그램에 정적으로 링크됩니다.
              이것은 멀티쓰레드나 재진입(re-entrant) 프로그램에는 안전하지 
              못합니다.

Libcd.lib     표준 C Runtime 라이브러리의 Debug 버젼입니다. Debug 빌드에선 
              Libc.lib 대신 이것을 사용합니다. 이것은 프로그램에 정적으로 
              링크됩니다.

Libci.lib     표준 C 라이브러리입니다.이 라이브러리는 Libc.lib 와 비슷하지만,
              이것은 이전 버젼의 Visual C++ 에서 제공된 표준 라이브러리에서
              지원된 표준 iostream 라이브러리와의 호환성을 제공합니다.
              (iostream이 구형이라는 얘기죠..) 이것은 프로그램에 정적으로
              링크됩니다.

Libcid.lib    구형 iostream 버젼이 포함된 표준 C 라이브러리의 Debug버젼입니다.
              역시 프로그램에 정적으로 링크됩니다.

Libcimt.lib   구형 iostream 버젼이 포함된 표준 C 라이브러리의 멀티쓰레드에 
              안전한 버젼입니다. 역시 프로그램에 정적으로 링크됩니다.

Libcimtd.lib  구형 iostream 버젼이 포함된 표준 C 라이브러리의 멀티쓰레드버젼의
              Debug 빌드입니다. 역시 프로그램에 정적으로 링크됩니다.

Libcmt.lib    멀티쓰레드 프로그램이나 재진입 프로그램에서도 사용이 안전한 
              sprintf() 나 strcpy() 같은 함수들이 포함된 C 런타임 라이브러리의
              멀티쓰레드 버젼입니다. 역시 프로그램에 정적으로 링크됩니다.

Libcmtd.lib   바로위의 Libcmt.lib의 디버그 버젼입니다. 
              역시 프로그램에 정적으로 링크됩니다. 

Libcp.lib     표준 C++ 런타임 라이브러리 입니다. 이것은 호출하는 프로그램에 
              정적으로 링크되며, 멀티쓰레드나 재진입 프로그램에 안전하지 
              못합니다.

Libcpd.lib    표준 C++ 런타임 라이브러리의 Debug 버젼입니다. 
              역시 프로그램에 정적으로 링크됩니다.

Limcpmt.lib   표준 C++ 런타임 라이브러리의 멀티쓰레드 버젼입니다. 
              역시 프로그램에 정적으로 링크됩니다.

Libcpmtd.lib  멀티쓰레드 C++ 표준 라이브러리의 디버그 버젼입니다. 
              역시 프로그램에 정적으로 링크됩니다.

Loadperf.lib  이 임포트 라이브러리는 Performance Counter 에 관련된 레지스트리 
              값들의 초기화를 지원하는 루틴들을 포함합니다. 
              이 라이브러리는 보통 인스톨 프로그램들에 사용됩니다.

Lz32.lib      Lempel-Ziv압축해제 루틴 라이브러리입니다. 보통 인스톨 프로그램에
              의해서 사용됩니다. 이 라이브러리는 압축루틴이 없으며, 
              단지 압축해제루틴만 들어있습니다.

Mapi32.lib    Microsoft Mail API 라이브러리 입니다..

Mfcapwz.lib   Custom Wizard의 개발을 가능하게 해주는 클래스와 함수들이 포함된
              라이브러리입니다.

Mfcclwz.lib   Custom Wizard의 개발을 가능하게 해주는 클래스와 함수들이 포함된
              라이브러리입니다.

Mfcuia32.lib  OLE 공통 사용자 인터페이스(Common User Interface)에 대한 MFC 의
              구현부분이 들어있습니다. Oledlg.lib 와 비슷하지만 Unicode 대신 
              ANSI 인터페이스를 지원합니다.

Mgmtapi.lib   SNMP(Simple Network Management Protocol) Management API입니다.

Mpr.lib       연결관리(Connection Management)를 위한 LAN Manager 스타일의 
              네트웍 API 가 들어있습니다. 이 API 들은 Windows 상에서 Connect와
              DIsconnet 를 가능하게 합니다.

Msacm32.lib   Microsoft Audio Compression Manager API(오디오 압축 관리자 API) 
              입니다. 이것은 Audio Waveform 데이타를 압축하고 해제하는 
              유틸리티들입니다.

Msconf.lib    Microsoft ActiveX Conferencing API 에 대한 라이브러리입니다.

Mslsp32.lib   License Service API 에 대한 임포트 라이브러리입니다.

Msvcirt.lib   구형 iostream 버젼이 포함된 표준 C 라이브러리의 DLL Build에 대한
              임포트 라이브러리 입니다. 이 라이브러리는 Libci.lib 라이브러리의
              DLL 버젼에 대한 임포트 라이브러리입니다.

Msvcirtd.lib  Mscvirt.lib 라이브러리의 디버그 버젼에 대한 임포트 라이브러리
              입니다.

Msvcprt.lib   표준 C++ 라이브러리의 DLL Build 에 대한 임포트 라이브러리입니다.
              이것은 Libcp.lib 라이브러리의 DLL 버젼에 대한 임포트 라이브러리
              입니다. 

Msvcprtd.lib  Msvcprt.lib 라이브러리의 디버그 버젼에 대한 임포트 라이브러리
              입니다.

Msvcrt.lib    표준 C 라이브러리의 DLL Build 에 대한 임포트 라이브러리입니다.
              이것은 Libc.lib 라이브러리의 DLL 버젼에 대한 임포트 라이브러리
              입니다.

Msvcrtd.lib   Msvcrt.lib 라이브러리의 디버그 버젼에 대한 임포트 라이브러리
              입니다. Retail Build 에서 Msvcrt.lib 를 사용한다면 Debug Build 
              에서 이것을 사용하십시오.

Mswsock.lib   Windows Sockets 2 API 에 대한 Microsoft 의 특정 확장부분
              (MS-Specific Extension)에 대한 임포트 라이브러리입니다.

Mtx.lib       Microsoft Transaction Server(MTS) 프로그래밍 인터페이스 
              라이브러리입니다.

Mtxguid.lib   MTS 에 의해 지원되는 객체들의 Guid 들을 가지고 있는 
              라이브러리입니다.

Nddeapi.lib   Network DDE API 입니다. DDE 스타일의 서비스를 네트웍을 통하여
              시스템간에 사용가능하도록 해줍니다.

Netapi32.lib  LAN Manager API Interface 입니다. 이 라이브러리는 MS 의 NOS
              (Network Operation System)에 의해 제공되는 저수준의 기능들을 
              사용하도록 해주는 함수들을 포함하고 있습니다.

Newmode.obj   당신의 Application 이 malloc() 함수 호출에 실패했을때 new 
              연산자의 에러 처리 메커니즘을 사용하도록 하여줍니다. 기본적으로,
              이것이 동작하지는 않습니다: malloc() 이 실패한다면, NULL 을 
              리턴하지 예외를 발생시키지(Throw) 않습니다.               
              이 모듈과 링크하는것은 malloc() 호출 실패시 new 연산자의 에러
              처리루틴을 호출하는 것으로 C 런타임 라이브러리의 동작을 
              변경합니다.

Ocx96.lib     OCX 96 스펙(Specification)에 명시된 인터페이스들에 대한 
              UUID들이 포함된 라이브러리입니다.

Odbc32.lib    ODBC API 라이브러리입니다. 이 라이브러리는 데이터베이스 
              응용프로그램에 대한 하부 독립적인 API 들을 제공합니다. 
              이 라이브러리는 MFC 에 의해 다시 추상화 됩니다.

Odbccp32.lib  ODBC control panel applet(제어판에 등록되는 응용프로그램) 에
              관한 인터페이스가 포함된 라이브러리입니다.

Oldnames.lib  "Kernighan and Ritchie C" 와 호환되는 이름을 가진 
              표준 C 런타임 라이브러리 함수들입니다. 이 라이브러리는 K&R-C의
              execv() 같은것을 ANSI-C 의 같은 함수인 _execv() 에 매핑(Mapping)
              해줍니다. 

Ole32.lib     32-bit OLE 지원을 위한 Core 라이브러리입니다.

Oleaut32.lib  32-bit Automation interface에 대한 라이브러리입니다.

Oledlg.lib    OLE 공통 사용자 인터페이스(Common User Interface)에 대한 System 
              Implementation입니다. OleUiEditLinks() 나 OleInsertObject()와 
              같은 함수들을 포함합니다.

Olepro32.lib  OLE Property Frame API 입니다. 또한 OLE Font (IFont) 나 Picture
             (IPicture) 프로퍼티 들에 대한 구현도 포함하고 있습니다.

Opengl32.lib  OpenGL 의 Core 함수 라이브러리입니다. 
              OpenGL 은 Silicon Graphics에 의해 정의되고 Microsoft 에 의해 
              Win32 용으로 구현된 Graphic Rendering Language 입니다. 
              Glu32.lib 와 Glaux.lib 도 참조하십시오.

Pdh.lib       Performance Data 헬퍼함수들에 대한 임포트 라이브러리 입니다. 
              이 Win32 API의 부분들은 프로세스에대해 Performance Counter 들을
              작성하고,질의하고,갱신하는것을(Create,Query,Update) 도와주는 
              쉬운 인터페이스들을 포함하고 있습니다.

Penwin32.lib  Pen Computing 용 Windows에 대한 확장 라이브러리입니다.

Pkpd32.lib    Pen Windows 의 커널함수들입니다.

Rasapi32.lib  클라이언트용 Remote Access Service(RAS) API 입니다. 
              이 라이브러리에 있는 함수들은 모뎀이나 그 비슷한 저속회선 연결을
              통해 원격지 컴퓨터에 연결하도록 해줍니다. 

Rasdlg.lib    RAS 응용프로그램에 대한 Common User Interface 요소들을 포함하고
              있는 라이브러리입니다.

Rassapi.lib   RAS 서버쪽 API 들입니다.

Rpcndr.lib    Remote Procedure Call(RPC) Helper Function API 들입니다.

Rpcns4.lib    RPC Name Service 함수들 입니다.

Rpcrt4.lib    RPC Windows run-time 함수들 입니다.

Scrnsave.lib  화면보호기(Screen saver) 에 대한 인터페이스입니다.

Setargv.obj   이 모듈과 링크하는 것은 콘솔 프로그램이 Wildcard(*,?) 를 사용한 
              Command Line Parameter들을 실제 파일이름들로 지정하도록 확장하여
              줍니다. 각 파일은 main() 의 argv 인자에 들어가게 됩니다. 
              윈도우에서 사용하려면 Wsetargv.obj 를 살펴보십시오.

Setupapi.lib  파일 설치와 삭제에 관련된 함수들입니다. 셋업프로그램에서 
              사용됩니다.

Shell32.lib   Windows Interface Shell API 들입니다. 이 API 들은 예를 들어 
              Norton Desktop for Windows와 같은 프로그램에 사용된 실행파일에서
              아이콘을 추출하거나 Command Line Parameter 를 사용해 다른 
              프로그램을 실행하는등의 기능을 제공합니다.

Snmpapi.lib   Simple Network Managerment Protocol(SNMP)에 관련된 주 API 함수들
              입니다. TCP/IP 네트웍에 대해 이 프로토콜은 Gateway 나 연결될 
              네트웍들을 모니터링하는데 사용됩니다. Mgmtapi.lib 와 연관되어 
              있습니다.

Svrapi.lib    Inter-Server Communication 에 관한 Network API 들입니다.

Tapi32.lib    Microsoft Telephony API(TAPI) 라이브러리입니다. lineOpen() 과 
              같은 telephony API 들을 구현합니다.

Th32.lib      32-bit Toolhelp 라이브러리입니다. 이 라이브러리는 Debugger 나 
              저수준의 툴을 작성할때 도움을 주는 함수들을 제공합니다. 
              예를들어 이 라이브러리의 루틴들을 윈도우상에서 프로세스나 
              쓰레드들을 Enumerate 하게 해줍니다.

Thunk32.lib   Thunk 컴파일러의 런타임 지원 루틴들입니다.
              (Thunking 이 뭔지 아시죠?)

Url.lib       이 파일은 URL 을 Parsing 하거나 MIME 헤더를 해석하는데 사용하는
              루틴입니다. 이 라이브러리에 있는 함수들은 현재 문서화가 되어있지
              않으며, 이것은 Win32 SDK 의 이후 버젼이나 Visual C++ 의 이후버젼
              에서 더 정제되고, 무리없게 지원될것입니다. 

Urlmon.lib    URL 모니커(moniker)의 런타임 지원 라이브러리에 대한 임포트 
              라이브러리입니다.

User32.lib    윈도우즈의 USER.EXE 에 대한 임포트 라이브러리 입니다. 
              이 라이브러리와 링크하는 것은 프로그램이 Windows 의 UI 부분을 
              사용할수 있도록 해줍니다. 이 라이브러리는 CreateDialog() 나 
              CreateWindow() 같은 함수를 포함합니다.

Uuid.lib      Stock(내장된) OLE 객체에 대한 표준 UUID 들입니다.

Vdmdbg.lib    이 라이브러리에 있는 함수들은 NT VDM 안에서 디버깅 하는것에 
              관련된 기능들을 지원합니다.

Version.lib   GetFileVersion() 과 같은 버젼 확인 API 들입니다.

Vfw32.lib     Video for Windows API 들입니다. 이 라이브러리에 있는 함수들은 
              Multimedia 비디오와 오디오를 재생,녹음,수정,저장 하는것을 
              가능하게 합니다.

Webpost.lib   WebPost API 임포트 라이브러리입니다. 이 라이브러리는 ISP
              (internet Service Provider)에 의해 제공되는 웹 사이트에 사용자의
              컴퓨터에서 데이타를 올리는것이 가능하도록 도와줍니다.

Win32spl.lib  Win32 spooler API 입니다. 이 파일에 있는 루틴들은 다른 프로그램
              이나 컴퓨터들로부터 Print Spooler Status에 접근하는것을 가능하게
              해줍니다.

Wininet.lib   Windows Internet Client API 들입니다.

Winmm.lib     Windows Multimedia API 들입니다. Multimedia Device Management, 
              Timer, Wave 파일, Multimedia I/O 제어함수 같은 것을 포함합니다.

Winspool.lib  The Win32 spooler API 입니다. 이 라이브러에 보이는 루틴들을 
              프로그램이 프린트 하는 동안 Windows Print Spooler 의 기능을
              사용하도록 해줍니다.

Winstrm.lib   Windows NT의 TCP/IP interface들 입니다. 이 파일은 TCP/IP Routing
              함수같은 것들을 제공합니다.

Wintrust.lib  ActiveX 객체에 대한 Trust Verification(신용확인) 에 관한 API들의
              임포트 라이브러리입니다. 이것은 WinVerifyTrust() 같은 함수들을 
              사용가능하도록 합니다.

Wow32.lib     이 라이브러리는 16-Bit 와 32-Bit 객체간에 핸들을 변형하도록 하는
              Generic Thunking 메커니즘에 의해 사용됩니다. 이 라이브러리는 
              또한 16 Bit 프로세스에서 32-Bit 메모리를 관리하도록 하는것을 
              도와줍니다.

Ws2_32.lib    Windows Sockets 2.0 API 입니다.

Wsetargv.obj  이 모듈과 링크하는 것은 Windows 프로그램이 Wildcard(*,?) 를 
              사용한 Command Line Parameter 들을 실제 파일이름들로 지정하도록
              확장하여 줍니다. 각 파일은 main()의 argv 인자에 들어가게 됩니다.
              콘솔 프로그램에 사용하려면 setargv.obj 를 살펴보십시오. 

Wsock32.lib   Windows Sockets APIs.

Wsock32.lib   Windows Sockets API 입니다.

Wst.lib       Working Set Tuner DLL 에 대한 인터페이스 입니다. 
              Working Set Tuner DLL 은 프로그램을 조사하여 프로그램의 
              Working Set 을 최소화하도록 도와줍니다.

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

참고할점은 주 API 들과, 헤더 파일 그리고 라이브러리들의 요약이 Lib 디렉토리에 
있는 Win32api.csv 에 들어있다는 것입니다. 이 파일은 Comma Separated Variable 
File(*.csv) 이며,  엑셀같은 스프레드쉬트 프로그램에서 읽어들일수 있습니다.
 

--- 이것으로 해서 끝이네요.. 회사에서 점심,저녁시간에만 번역을 하다보니 
    시간이 한참 걸렸습니다. 도움이 되었으면 좋겠네요.. 그럼 이만..
 

[Error/Warning] 빌드할 때 문제가 발생했다면 여기로!

저장소/VC++
VC++ 빌드 시 발생하는 Error 또는 Warning에 대한 설명이 한가득~
모르면 이쪽부터 참고하자.


[자료 출처 - MSDN]
C/C++ 빌드 참조  http://msdn.microsoft.com/ko-kr/library/91621w01(VS.80).aspx

[Error/Warning] warning LNK4098

저장소/VC++
링크에 사용되는 RunTime Library와 충돌이 발생했을 때 발생하는 경고.

프로젝트 속성 중 RunTime Library를 다중 스레드 DLL(Multi Thread DLL)(/MD)로 변경할 경우
msvctr Library를 사용하게 된다.
이럴 경우 기본으로 사용되는 libcmt Library(다중 스레스(Multi Thread)(/MT)) 와 충돌을 일으켜 경고를 발생한다.
해결 방법으로는 프로젝트 속성 페이지의 명령줄에 /NODEFAULTLIB:libcmt.lib 를 추가하거나
특정 라이브러리 무시 항목에 libcmt.lib 를 추가하고 다시 빌드하면 된다.

MSDN에서 퍼온 아래의 내용도 참고하자.

[자료 출처]
MSDN http://msdn.microsoft.com/ko-kr/library/6wtdswk0(VS.80).aspx

링커 도구 경고 LNK4098

오류 메시지

'library' defaultlib가 다른 라이브러리와 충돌합니다. /NODEFAULTLIB:library를 사용하십시오.
defaultlib 'library' conflicts with use of other libs; use /NODEFAULTLIB:library

호환되지 않는 라이브러리에 링크하려고 했습니다.

Note참고

런타임 라이브러리에는 여러 형식이 혼합 사용되지 않도록 하는 지시문이 들어 있는데 여러 형식이나 디버그/비디버그 버전의 런타임 라이브러리를 동일한 프로그램에서 사용하려고 하면 이 경고가 발생합니다. 예를 들어, 어떤 종류의 런타임 라이브러리를 사용하는 파일을 컴파일하고 다른 종류의 런타임 라이브러리를 사용하는 파일을 컴파일한 다음(예: 단일 스레드 라이브러리와 다중 스레드 라이브러리) 이 둘을 링크시키려고 하면 이 경고가 발생합니다. 동일한 런타임 라이브러리를 사용하는 소스 파일을 컴파일해야 합니다. 자세한 내용은 런타임 라이브러리 사용(/MD, /MT, /LD) 컴파일러 옵션을 참조하십시오.

링커의 /VERBOSE:LIB 스위치를 사용하여 링커가 검색 중인 라이브러리를 확인할 수 있습니다. 예를 들어, LNK4098이 발생하여 단일 스레드된 비디버그 런타임 라이브러리를 사용하는 실행 파일을 만들려는 경우에는 /VERBOSE:LIB 옵션을 사용하여 링커에서 검색 중인 라이브러리를 확인하십시오. 링커는 검색한 라이브러리로 LIBC.lib를 출력하며 LIBCMT.lib, MSVCRT.lib, LIBCD.lib, LIBCMTD.lib 또는 MSVCRTD.lib는 출력하지 않습니다. 무시할 각 라이브러리에 대해 /NODEFAULTLIB를 사용하여 링커가 잘못된 런타임 라이브러리를 무시하도록 할 수 있습니다.

다음 표는 사용할 런타임 라이브러리에 따라 무시해야 하는 라이브러리를 보여 줍니다.

사용할 런타임 라이브러리 무시해야 하는 라이브러리

단일 스레드(libc.lib)

libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib

다중 스레드(libcmt.lib)

libc.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib

DLL을 사용하는 다중 스레드(msvcrt.lib)

libc.lib, libcmt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib

디버그 단일 스레드(libcd.lib)

libc.lib, libcmt.lib, msvcrt.lib, libcmtd.lib, msvcrtd.lib

디버그 다중 스레드(libcmtd.lib)

libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, msvcrtd.lib

DLL을 사용하는 디버그 다중 스레드(msvcrtd.lib)

libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib

예를 들어, 이 경고가 발생한 경우와 비디버그, 단일 스레드 버전의 런타임 라이브러리를 사용하는 실행 파일을 만들려는 경우에는 링커에 다음 옵션을 사용하면 됩니다.


[C++] DLL에서 메모리 할당, 외부에서 해제

저장소/VC++

아... 네이버님과 구글신께 물어봤으면 금방 해결할거를
하루종일 삽질하고있었기에 정리한다.

좋은 프로그래밍 습관 중 하나는 '메모리는 가급적 할당한 곳에서 해제하자.' 라고 할 수 있다.
사실 이 습관만 제대로 지킨다면 수많은 메모리 문제에서 약간은 해방될 수 있다고 생각한다.
물론 경우에 따라 다르겠지만 가급적이면 그렇게 하는 것이 좋다는거다.

이번에 생긴 문제는 제목 그대로 DLL에서 할당한 메모리는 외부에서 해제할 때 발생하였다.
(앞, 뒤 자르고 결론부터 말하자면 프로젝트 속성 중 '런타임 라이브러리'를 '다중 스레드 DLL'로
변경하니 잘 된다는거..;;;)
export한 DLL Function의 파라미터 중 하나를 STL list를 받게 구성하고 DLL 내부에서 문자열을 동적 할당한, list에 밀어넣고 외부에서 필요한 일을 한 후 delete할 때 문제 발생!!! 크아아아~
모르겠다 @_@

원인과 해결책은 이렇다고 한다.
DLL내부에서 STL객체를 생성하고 외부에서 STL객체를 사용 후 해제하려고 하면 access violation 발생한다. STL에서는 static data멤버를 사용한다. DLL내부(A라고 하자)에 STL객체를 생성하면 DLL내부에서는 static  data 멤버를 사용하게 된다. DLL을 이용하는 외부DLL/EXE(B라고 하자)에서 DLL내부(A)에 생성한 STL객체를 포인터나 레퍼런스로 접근가능 하지만, 외부 DLL/EXE(B)에서 STL객체를 사용하면 외부 DLL/EXE(B)에 STL에서 사용하는 static data멤버가 DLL(A)와 독립적으로 생성이 되기 때문에 외부DLL/EXE(B)에서 메모리를 해제하려고 하면 sync가 맞지않아 access violation이 발생하게 되는 것이다.
  위의 문제를 해결하는 방법은 아래와 같다.
  1) STL에서 생성한 객체를 접근하는 method를 export한다.
  2) 템플릿 클래스 인스턴스를 export하고 사용하는 곳(B)에서 import한다.
  3) 위 방법보다 간단한 방법으로 VC++ .NET의 경우 프로젝트 셋팅에서 "다중 쓰레드 DLL(/MD, release 모드)"나 "다중 쓰레드 디버그 DLL(/MDd, debug모드)"로 모두(A, B) 설정해주면 된다.

[출처 : http://jglee.egloos.com/1015547] 맘대로 퍼와서 미안해요;;

 
MS에 이러한 내용이 있으니 참고~ (달달 외우는게 좋을까?)

[STL (표준 템플릿 라이브러리) 클래스와 STL 개체가 데이터 구성원을 포함하고 있는 클래스 인스턴스를 내보내는 방법]
http://support.microsoft.com/kb/168958/
[포인터 또는 다른 DLL 또는 EXE 참조를 통해 STL 개체에 액세스할 때 액세스 위반이 발생할 수 있습니다.]
http://support.microsoft.com/kb/q172396/


아무튼 삽질이여 안녕~

[C++] CRT Debug Heap(Memory Leak 확인 방법)

저장소/VC++

MFC 프로젝트에서는 이런거 필요 없다능...
귀찮아도 해두는 편이 좋으니까 적어둔다능... -_-;

우선 MSDN 링크
[CRT 디버그 힙] 
http://msdn.microsoft.com/ko-kr/library/aa292300(VS.71).aspx
[디버그 힙] http://msdn.microsoft.com/ko-kr/library/aa292313(VS.71).aspx

링크가 그게 그거임 -_-;
정리한 내용보다 링크가 훨 나음;;
그래도 일단 정리~


C Runtime(CRT) 환경에서 Memory Leak을 확인하는 방법은 아래와 같다.
C Runtime Library인 "crtdbg.h"를 이용하여 디버깅 중 확인할 수 있다.

#include <crtdbg.h>

#define _CRTDBG_MAP_ALLOC

#ifdef _DEBUG
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif

근데 이 내용 MFC 책에서 봤는데... 제목이 뭐였더라;;;
아무튼 일단 저렇게 해두면 됨.
그 다음은 아래와 같다.

일단 진입부에서 아래와 같이 설정한다.
예를 들어 main() 함수가 진입 시작점일 경우

int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
...
}

이렇게 해두면 Memory Leak 발생시 MFC에서 보던 것 처럼 나온다.

각 Flag에 대한 설명은 아래와 같다.

 

비트 필드

기본값

설명

_CRTDBG_ALLOC_MEM_DF

On

디버그 할당을 사용합니다. 이 비트를 해제하면 할당은 함께 연결되어 있지만 블록 형식은 _IGNORE_BLOCK입니다.

_CRTDBG_DELAY_FREE_MEM_DF

Off

부족한 메모리 조건을 시뮬레이션하는 것과 관련해서 메모리가 실제로 해제되는 것을 방지합니다. 이 비트를 설정하면, 해제된 블록이 디버그 힙의 연결 리스트에 보관되지만 _FREE_BLOCK으로 표시되고 특별한 바이트 값으로 채워 집니다.

_CRTDBG_CHECK_ALWAYS_DF

Off

모든 할당 및 할당 취소에서 _CrtCheckMemory를 호출하게 합니다. 실행 속도는 지연되지만 오류를 신속하게 찾아 냅니다.

_CRTDBG_CHECK_CRT_DF

Off

_CRT_BLOCK 형식으로 표시된 블록을 누수 탐지와 상태 구별 작업에 포함시킵니다. 비트를 해제하면 위와 같은 작업을 하는 동안 런타임 라이브러리가 내부적으로 사용하는 메모리를 무시합니다.

_CRTDBG_LEAK_CHECK_DF

Off

_CrtDumpMemoryLeaks를 호출하여 프로그램을 종료할 때 누수 검사를 수행합니다. 응용 프로그램이 할당한 모든 메모리를 해제하는 데 실패하면 오류 보고서가 생성됩니다.


여기까지는 준비 과정(?)일 뿐이고 실제로 메모리 릭이 발생했을 때 확인하고자 하는 곳에서 브레이크 포인트를 걸려면 아래와 같이 메모리 할당 번호를 지정하여 확인한다.

int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_crtBreakAlloc(메모리 할당 번호);
...
}

이렇게 하면 원하는 메모리 위치를 확인할 수 있다.
열심히 디버깅 하세~ 예~ 붸뷔~ 요~ 체키라웃~

[참고] MSDN, 네이버님, 여러 블로거님들

SQLite - 쿼리 실행

저장소/VC++

닥치고 샘플 ㄱㄱ~

// Insert에 사용될 데이터 구조체
typedef struct _my_value
{
// 이것 저것 있음

} MY_VALUE, *PMY_VALUE;

sqlite3* g_pDB = NULL;

int TestFunc_Open(const char* pszDBFilePath);
int TestFunc_Close();
int TestFunc_QueryExec1(const char* pszTableName,
    const char* pszQuery,
    sqlite3_callback xCallback);
int TestFunc_QueryExec2(const char* pszTableName, const char* pszQuery);
int TestFunc_QE_Insert(const char* pszTableName,
 int nColumnCount,
 std::list<PMY_VALUE>* plstValues);


int TestFunc_Open(const char* pszDBFilePath)
{
// 파라미터검증 생략

int nRet = SQLITE_OK;
nRet = sqlite3_open_v2(pszDBFilePath,
&g_pDB,
SQLITE_OPEN_READWRITE,
NULL);
if(SQLITE_OK != nRet)
{
// 이쯤에서 적절한 에러처리.
}

return 0;
}

int TestFunc_Close()
{
if(NULL != g_pDB)
{
 int nRet = SQLITE_OK;
nRet = sqlite3_close(g_pDB);
if(SQLITE_OK != nRet)
{
// 아이고~ 실패입니다요! 에러처리!
}
}

return 0;
}

/*
 sqlite3_exec 함수를 사용한 방식
 sqlite3_exec 함수는 내부에서 아래와 같은 과정으로 처리됨.
 (sqlite3_prepare -> sqlite3_step -> sqlite3_finalize)
 단일 명령 처리에는 사용하기 편하지만
 빠르고 연속적인 쿼리를 처리하기엔 오버헤드를 무시할 수 없음.
*/
int TestFunc_QueryExec1(const char* pszTableName,
    const char* pszQuery,
    sqlite3_callback xCallback)
{
// 파라미터 및 이것저것 검증 생략

int nRet = SQLITE_OK;
char* pszErrMsg = NULL;
nRet = sqlite3_exec(g_pDB, pszQuery, xCallback, NULL, &pszErrMsg);
if(SQLITE_OK != nRet)
{
// 실패 원인 확인 1. Code
int nErrCode = sqlite3_errcode(g_pDB);

// 실패 원인 확인 2. Message
const char* pszErrMessage = sqlite3_errmsg(g_pDB);

// 실패 원인 확인 3. 반환된 Error Message
// pszErrMsg <- 요거요거
// 반환된 Error Message는 알아볼거 알아보고 나중에
// sqlite3_free를 통해 메모리 해제를 해줘야 한다고 한다.
// (참고로 잘못된 대상으로 sqlite3_free를 사용하면 뻗어버린다!)
sqlite3_free((void*)pszErrMsg);
}

return 0;
}

/*
 sqlite3_prepare 함수를 사용한 방식
 sqlite3_exec 함수를 사용한 것보다 귀찮긴 하지만
 sqlite3_bind_xxx 함수와 sqlite3_reset 함수를 활용하여 쿼리의 재사용성을 높일 수 있다.
 작업의 끝은 sqlite3_finalize 함수 호출로 막을 내린다.
*/
int TestFunc_QueryExec2(const char* pszTableName, const char* pszQuery)
{
 // 파라미터 및 이것저것 검증 생략

int nRet = SQLITE_OK;
sqlite3_stmt* pStmt = NULL;

// 실행할 쿼리를 준비하고
nRet = sqlite3_prepare(g_pDB, pszQuery, -1, &pStmt, NULL);
if(SQLITE_OK == nRet)
{
// 준비된 쿼리를 실행한다.
nRet = sqlite3_step(pStmt);
while(SQLITE_ROW == nRet)
{
// 뭐 필요한 작업 있으면 여기서
nRet = sqlite3_step(pStmt);
}

nRet = sqlite3_finalize(pStmt);
}
else
{
// 에러처리
}

return 0;
}

int TestFunc_QE_Insert(const char* pszTableName,
 int nColumnCount,
 std::list<PMY_VALUE>* plstValues)
{
// 파라미터 및 이것저것 검증 생략

// 대량의 INSERT를 처리할 경우 BEGIN ~ COMMIT 을 쓰면 속도가 빠르다고 함.
// 임시파일 어쩌구 하던데 자세히 모르니까 나중에 다시 찾아보도록...
int nRet = SQLITE_OK;

nRet = sqlite3_exec(g_pDB, "BEGIN;", NULL, NULL, NULL);

char szBind[100] = "?";
for(int i = 0 ; i < nColumnCount ; i++)
{
strncat_s(szBind, 100, ", ?", _TRUNCATE);
}

char szQuery[512] = {0,};
strncpy_s(szQuery, 512, "INSERT INTO ", _TRUNCATE);
strncat_s(szQuery, 512, pszTableName, _TRUNCATE);
strncat_s(szQuery, 512, " VALUES(", _TRUNCATE);
strncat_s(szQuery, 512, szBind, _TRUNCATE);
strncat_s(sqQuery, 512, ");", _TRUNCATE);

sqlite3_stmt* pStmt = NULL;
nRet = sqlite3_prepare(g_pDB, szQuery, -1, &pStmt, NULL);
if(SQLITE_OK == nRet)
{
std::list<PMY_VALUE>::iterator iter;

for(iter = plstValues->begin() ; iter != plstValues->end() ; ++iter)
{
PMY_VALUE pValue = *iter;

nRet = sqlite3_reset(pStmt);

// Column 수에 맞게, 데이터 형식에 맞게 sqlite3_bind 함수를 사용하여
// 필요 값을 넣는다.
sqlite3_bind_int(pStmt, 1, pValue->xxx);
sqlite3_bind_double(pStmt, 2, pValue->aaa);
sqlite3_bind_text(pStmt, 3, pValue->bbb, -1, SQLITE_STATIC);

// 완성된 쿼리 실행
nRet = sqlite3_step(pStmt);
whlie(SQLITE_ROW == nRet)
{
nRet = sqlite_step(pStmt);
}
}

nRet = sqlite3_finalize(pStmt);
}

nRet = sqlite3_exec(g_pDB, "COMMIT;", NULL, NULL, NULL);

return 0;
}

SQLite - 쿼리 실행(어떤거 써야해?)

저장소/VC++

sqlite3_exec로 Query 실행이 가능하다.

허나!! 또 다른 것이 있었네? 이건 뭐냐?
원문 보니까 보니까 영 이해 안된다.(영어 실력 부족;;;) -_-

일단 네이버님께 물어물어 뒤져보니 대략 이렇다.

1. sqlite3_open
2. sqlite3_stmt
3. sqlite3_prepare
4. sqlite3_bind
5. sqlite3_step
6. sqlite3_reset
7. sqlite3_finalize
8. sqlite3_close

하아... 골아프군.
설명을 하자면 이렇다. (정확한지 모르겠으니 나중에 다시 정리하자)

sqlite3_open과 sqlite3_close는 아니까 패스.
sqlite3_stmt는 statement로 sqlite3_prepare와 sqlite3_bind_xxx에서 사용된다.
sqlite3_prepare를 실행하여 쿼리를 준비한다.
Query에 Data Type 별로 값을 정해주려면 sqlite3_bind_xxx를 통해서 값을 추가한다.
sqlite3_step으로 준비된 stmt(그냥 Query라고 생각하면 될 것 같다.)를 실행한다.
sqlite3_prepare를 통해 생성된 sqlite3_stmt를 다시 활용하려면 sqlite3_reset을 하면 된다.
Query 실행을 끝내려거든 sqlite3_finalize를 해주면 된다.

일단 찾아본 내용으로는 이러한 과정을 거치는데
요걸 좀 더 편하게 사용할 수 있게 해주는 것이 sqlite3_exec라고 한다.

결론!
그냥 쉽게 만들려면

1. sqlite3_open
2. sqlite3_exec
3. sqlite3_close

이렇게 해주면 되겠지만... 이렇게 만들어야 쓰겠어?
사용상 편의를 위해 저기 위에 있는 1~8번 과정을 거치도록 만드는 것이 좋을 것 같다.

에휴... 제대로 해석이 되거든 다시 정리해야겠다.
영어영어영어영어영어영어영어영어영어영어영어영어영어영어영어영어영어영어영어영어
잊지 않겠다. -_-+

[MFC] MFC에서 Thread를 사용할 때는 _beginthread 말고 AfxBeginThread를 사용해야 한다.

저장소/VC++

[출처] [펌글] MFC 에서 쓰레드 관련한 글 |작성자 구리구리


MFC 프로그래밍에서 거의 100% 들어맞는 원칙이 하나 있습니다.
비슷한 기능을 하는 함수가 C/C++ 런타임 라이브러리 API 버전이 있고 앞에 Afx가 붙은 MFC 버전이 있다면 무조건 Afx가 붙은 버전을 써야 한다는 겁니다.
예를 들어, LoadLibrary 같은 것도 MFC에선 AfxLoadLibrary를 써야 합니다.


이런 얘기를 꺼내는 건 다름이 아니라
많은 분들이 MFC에서 _beginthread나 CreateThread를 이용해서 스레드를 만든 다음
그 스레드에서 CWinApp, CView 등의 인스턴스에 액세스하면서 에러를 경험하시는 것 같아서 입니다.


(1) MFC 오브젝트는 '스레드 안전'하지 않습니다.
동일한 오브젝트를 두 스레드에서 동시에 사용하려고 하면 맛 갈 수 있습니다


(2) MFC CWinThread나 AfxBeginThread를 이용하지 않고, _beginthread나 CreateThread로 만든 스레드에서
MFC 오브젝트에 액세스하면 맛 갈 수 있습니다.


(3) MFC 스레드(보조 스레드)에서 다른 스레드로 생성된 CWnd 계열 오브젝트를 사용하면 생각대로 결과가 안 나올 수 있습니다.


MFC 오브젝트는 실제 HWND 같은 핸들을 감싸는 C++ 랩퍼 오브젝트인데, 각각의 랩퍼 오브젝트에 대응되는 실제 HWND 핸들이 무엇인지 알려주는 정보가 스레드마다 개별적으로 사용되는 스레드 로컬 스토리지에 저장되기 때문입니다.
즉 같은 CWnd 오브젝트(같은 메모리 주소)에 액세스하더라도 그 오브젝트가 사용하는 핸들(HWND)가 다를 수 있다는 겁니다.


그러니 보조 스레드에서 뭔가 UI와 관련된 조작을 할 때 직접 하려고 하지 말고
마치 2개의 프로세스가 통신하는 것처럼 ::PostMessage 같은 방법을 이용하는 것이 좋습니다.


또한, 예를 들어, 다른 스레드로 CWnd 오브젝트를 넘길 때 오브젝트를 직접 넘기지 말고 HWND로 넘긴 다음 받은 스레드에서 FromHandle 메소드를 써서 다시 CWnd를 사용하는 식으로 해야 합니다.


이상의 내용은, 왠만한 Visual C++ 프로그래밍 책에는 다 나올 겁니다.


http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_multithreading_with_c.2b2b_.and_mfc.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_Multithreading.3a_.Programming_Tips.asp


이 두 개의 글을 대충 정리한 것입니다.


출처 : 데브피아 vc++ 팁 강좌란 노영선(roh0sun)님 글입니다~~ 

[Win32] Thread 종료 확인 - GetExitCodeThread

저장소/VC++

thread의 상태(종료 여부)를 반환한다.
Retrieves the termination status of the specified thread.

BOOL WINAPI GetExitCodeThread(
   __in HANDLE hThread,
   __out LPDWORD lpExitCode
);


Parameters
hThread
  A Ahndle to the thread.
  The handle must have the THREAD_QUERY_INFORMATION access right. For more information, see Thread Security and Access Rights.

lpExitCode
  A pointer to a variable to receive the thread termination status. If the specified thread has not terminated and the function succeeds, the termination status returned is STILL_ACTIVE.

Return Value
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
 

Remarks

If the thread has terminated and the function succeeds, the termination status returned may be one of the following:

  • The exit value specified in the ExitThread or TerminateThread function.
  • The return value from the thread function.
  • The exit value of the thread's process.

Warning  If a thread happens to return STILL_ACTIVE (259) as an error code, applications that test for this value could end up in an infinite loop.

Requirements

Client

Requires Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95.

Server

Requires Windows Server 2008, Windows Server 2003, Windows 2000 Server, or Windows NT Server.

Header

Declared in Winbase.h; include Windows.h.

Library

Use Kernel32.lib.

DLL

Requires Kernel32.dll.






[Win32] 환경변수 설정 값 가져오기 - GetEnvironmentVariable

저장소/VC++

Retrieves the contents of the specified variable from the environment block of the calling process.

DWORD WINAPI GetEnvironmentVariable(
   __in    LPCTSTR lpName,
   __out  LPTSTR lpBuffer,
   __in    DWORD nSize
);

Parameters
   lpName
      The name of the environment variable.
   lpBuffer
      A pointer to a buffer that receives the contents of the specified environment variable as a null-terminated string. An environment variable has a maximum size limit of 32,767 characters, including the null-terminating character.




환경변수 레지스트리 위치

시스템 환경 변수

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\control\session Manager\Enviroment

사용자 환경 변수

HKEY_CURRENT_USER\Environment

 

바로 적용시키는 코드

 ::SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0,(LPARAM)TEXT("Environment"));

- 이하 아래 내용은 프로그램 내에서만 유효한 변경이다.

 

프로그램 내에서 환경변수 가져오기

 int nSize = ::GetEnvironmentVariable("TEMP", NULL, NULL);

 TCHAR* buffer = new TCHAR[nSize +1];

 ::GetEnvironmentVariable("TEMP",buffer, nSize);

// 만약 버퍼의 크기가 변수의 크기보다 작다면 0이 리턴 되므로 버퍼의 크기를 nSize만큼 얻어와야 한다.

 

프로그램 내에서 환경변수 설정하기

 ::SetEnvironmentVariable("TEMP", "C:\\tmp");

 

프로그램 내에서 환경변수 지우기

::SetEnvironmentVariable("TEMP", NULL);

 

예제)

 // * Map 처음 문자를 환경변수에 세팅
 char buf[50] = {0,};
 ::GetPrivateProfileString("CONFIG", "PRE_CHAR", "S", buf, 50, szCfgFile);
 SetEnvironmentVariable("PRE_CHAR", buf);

 

 char buf[30] = {0,};
 // 환경변수에서 Map 처음문자 가져오기
 GetEnvironmentVariable("PRE_CHAR", buf, 30);