'윈도우/스터디'에 해당되는 글 5건

  1. 2012.01.16 DLL (Dynamic Link Library) 정리
  2. 2011.12.15 Media Transfer Protocol (MTP)
  3. 2011.11.28 PostThreadMessage로 SendThreadMessage 구현하기
  4. 2011.11.28 _stprintf_s
  5. 2011.11.24 Visual Studio C++ 메모리 릭 (2)

광고 수익은 기아대책 서울본부에 기부합니다.

2012.01.16 16:40 윈도우/스터디

출처 : http://sol9501.blog.me/70102942944
출처 : http://psmon.x-y.net/xy_bb/board.php?id=PgSkill&board_sec=0&page=2&mode=view&total=46&no=25

기본적인것이 잘 정리된것 같아서.. 퍼왔습니다.

DLL (Dynamic Link Library)이란,

어플리케이션에서 동적으로 링크하여 사용할 수 있는 라이브러리를 말하며,
확장자로는 .dll, .fon, .drv, .exe 등이 사용된다.

장점으로는,
일단, 여러 어플리케이션이 사용한다면 메모리 낭비를 줄일 수 있겠고,
업그레이드및 모듈별관리가 용이한점을 들 수 있겠다.

구조는,
간단히 코드부분과 데이터로 구성되어있으며, 스택이 없다는 것이 특징이다.
//스택은 어플이케이션의 것을 사용한다
스택이 없으므로 독립적인 프로세스가 될 수 없으며
운영체제로 부터의 메세지를 받을 수 없다
내부에 Exported Function Table을 가지고 있으며,
서수 + 기호이름 + 실제함수를 가리키는 포인터로 구성되어 있다.

(MSDN-TechnicalArticles-VisualTools-VisualC++-Visual C++4.0- DLLs for Beginners 참조)

종류는,
- Regular DLL (Statically linked MFC DLL) : 배포시 자신의 DLL만 제공가능
- Regular DLL (using Shared MFC DLL) : 배포시 자신의 DLL과 MFC공유DLL을 같이 제공
-> 어플리케이션이 MFC이외의 경우에도 사용가능
C언어 기반의 인터페이스제공 필요.
- MFC Extension DLL (using Shared MFC DLL) : MFC로 작성된 어플리케이션에서만 사용가능

링킹방법으로는,
- Implicit Linking (암시적링킹)
- DLL + Lib + header file 필요.
- 어플리케이션 로딩때 같이 로딩.
- Explicit Linking (명시적링킹)
- 로딩타임 마음대로 결정가능 ( 예: 영문리소스/한글리소스 동적으로 결정 )
- 주요함수
- LoadLibrary : DLL모듈 로딩
- GetProcAddress : 함수의 포인터를 얻어옴
- FreeLibrary : DLL 종료 (reference counter를 1감소시킨다)

컴파일러 커맨드
- _WINDLL : 현재 프로젝트가 DLL임을 의미
- _USRDLL : Regular DLL임을 의미
- _AFXDLL : using Shared MFC DLL 임을 의미
- _AFXEXT : MFC Extension DLL임을 의미

일반적인 익스포트함수 예제

extern "C" declspec(dllexport) void WINAPI function(void);
// extern "C" : 컴파일때 decoration name을 생성하지 않도록 하기위해 (C-Style)
// declspec(dllexport/dllimport) : Export/Import된 함수임을 의미
// WINAPI
- "windef.h"의 119 line 에 _stdcall 로 정의되어 있음
- PASCAL calling convension을 의미 : push는 거꾸로(오른쪽에서 왼쪽), pop은 Callee가 담당.
- 참고로, C++은 디폴트로 _cdecl을 사용 : push는 거꾸로(오른쪽에서 왼쪽), pop은 Caller가 담당.

DLL 찾기 순서
1 어플리케이션(EXE)을 포함한 폴더
2 프로세스의 현재 폴더
3 시스템 폴더
4 윈도우즈 폴더
5 Path에 지정되어 있는 폴더들...


TIPs

1. DLL에 공유데이터를 포함시키기 위한 방법

- memory-mapped file을 사용하는 방법. (요건 나중에...)

- named data section을 사용하는 방법.

#pragma data_seg ("Shared")
int iShared = 0;
#pragma data_seg ()


2. DLL내에 있는 Resource 참조 방법

- 가장 일반적인 MFC 어플리케이션 + MFC Extension DLL 의 경우 리소스를 찾는 순서

1. 어플리케이션(EXE)의 리소스 검색
2. DLL의 리소스 검색
3. MFC공유DLL의 리소스 검색
-> 중복되는 리소스이름이 있는 경우는 먼저 찾아진 리소스를 사용하게 된다.
임의로 찾기 순서를 바꾸기 위해서
AfxSetResourceHandle(원하는 모듈의 리소스핸들)을 사용할 수 있다.
예) 다음의 코드는 DLL내에 있는 리소스를 먼저 찾기 위한 코드이다.
// DLL의 코드
Handle hInstOld = AfxGetResourceHandle(); // 어플리케이션의 리소스핸들을 보관.
AfxSetResourceHandle(DLL의 DllMain에서 얻은 DLL의 리소스핸들);
// ...
AfxSetResourceHandle(hInstOld); // 원래대로 복귀

- MFC 어플리케이션(or 델파이/비베...) + Regular DLL 의 경우.

- Regular DLL을 사용하는 경우에는 위와같이 DLL내의 리소스를 참조할 수 없다.
따라서 DLL내의 리소스(다이얼로그와같은)를 참조하기 위해서는,
다음과 같이 임의로 Module State를 전환시켜주는 함수가 필요하다.
- AFX_MANAGE_STATE(AfxGetStaticModuleState());
일반적으로 프로세스(EXE)의 인스턴스핸들은 거의 항상 0x00400000이고,
DLL은 0x10000000 이다.
DLL내에서 위의 함수를 사용한 후에는 인스턴스핸들이 DLL의 인스턴스핸들(0x10000000)로
바뀐 것을 확인해 볼 수 있을것이다.

- (어플리케이션 + ) Regular DLL + MFC Extension DLL

- Regular DLL에서 MFC Extension DLL내에 있는 리소스를 참조하려 할때 역시
그냥 되지는 않는다. 이때는 두가지 방법이 있는데,

첫번째는,

잠시 리소스를 참조하기 위해 사용되는 인스턴스핸들을 MFC Extension DLL의 것으로
바꿨다가 복구해주는 방법이다.

HINSTANCE hInstOld = AfxGetResourceHandle();
AfxSetResourceHandle(g_hModule);
m_menu.LoadMenu(IDR_LISTOUTPUT)
AfxSetResourceHandle(hInstOld); // restore the old resource chain

이 방법은 위의 리소스찾기 순서를 바꾸기 위해 사용했던 방법과 같다.
g_hModule은 DLLMain에 있던 hInstance를 전역변수로 보관한 것이다.

두번째는,

아래 소스는 MFC Extension DLL을 만들었을 때 만들어지는 소스의 일부이다.
잘 보고 가장 긴 주석문에서 시키는 대로 하면된다.

new CDynLinkLibrary(Implicit_MFCExt_dllDLL); 를 주석처리하고,
따로 함수를 만들어 익스포트 시킨다.
그리고, 그 함수를 Regular DLL의 InitInstance와 같은 함수에서
첨에 한번 초기화를 시키도록 해 주면 된다.
그러면 Regular DLL의 리소스체인에 attach된다.

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// Remove this if you use lpReserved
UNREFERENCED_PARAMETER(lpReserved);

if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("IMPLICIT_MFCEXT_DLL.DLL Initializing!\n");

// Extension DLL one-time initialization
if (!AfxInitExtensionModule(Implicit_MFCExt_dllDLL, hInstance))
return 0;

// Insert this DLL into the resource chain
// NOTE: If this Extension DLL is being implicitly linked to by
// an MFC Regular DLL (such as an ActiveX Control)
// instead of an MFC application, then you will want to
// remove this line from DllMain and put it in a separate
// function exported from this Extension DLL. The Regular DLL
// that uses this Extension DLL should then explicitly call that
// function to initialize this Extension DLL. Otherwise,
// the CDynLinkLibrary object will not be attached to the
// Regular DLL's resource chain, and serious problems will
// result.

//new CDynLinkLibrary(Implicit_MFCExt_dllDLL);

g_hModuleInstance = hInstance;
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("IMPLICIT_MFCEXT_DLL.DLL Terminating!\n");
// Terminate the library before destructors are called
AfxTermExtensionModule(Implicit_MFCExt_dllDLL);
}
return 1; // ok
}

extern "C" AFX_EXT_API void WINAPI InitMFCExtDLL()
{
// create a new CDynLinkLibrary for this app
new CDynLinkLibrary(Implicit_MFCExt_dllDLL);
}


저작자 표시 비영리 동일 조건 변경 허락
신고

'윈도우 > 스터디' 카테고리의 다른 글

DLL (Dynamic Link Library) 정리  (0) 2012.01.16
Media Transfer Protocol (MTP)  (0) 2011.12.15
PostThreadMessage로 SendThreadMessage 구현하기  (0) 2011.11.28
_stprintf_s  (0) 2011.11.28
Visual Studio C++ 메모리 릭  (2) 2011.11.24
posted by Town One townone
2011.12.15 10:25 윈도우/스터디


Media Transfer Protocol

휴대용미디어장치를위한미디어전송프로토콜클래스
 - 드라이버설치와관계없이PC와연결
 - 다양한디지털장치와호환
    ( 디지털카메라, PMP, 휴대용전화기, 기타등등)
마이크로소프트에서개발/소유
 - 산업표준의PTP (Picture Transfer Protocol)에서확장
 - PTP와의호환성제공
주요목적
 - 장치간의일반적미디어전송기능
 - 장치의관리및제어
 - 풍부한객체설명
 - 대용량볼륨에대한최적화
 - DRM(Digital Rights Management) 기능

MTP 의기능
주요기능
 - 객체기반의프로토콜
 - 업체별기능차별화및브랜드기능제공가능
 - 목록및 참조 기능
 - 장치관리
 - 업체별기능확장
 - 프로파일
 - 고성능전송
    PC로 200Mbps까지; 장치로는 80Mbps
장치기능구현의 독립성
 - 파일시스템
 - Accelerator 파일
 - 버스및전송형식

....


Introduction to MTP : Media Transfer Protocol
>>>



참고
http://dev.gardenquestions.com/ko/question/write-files-to-wpd-device-via-mtp-c-vb-net

MTP Device Enumeration on Windows (mssachlp.lib)
http://opensource.creative.com/mtp_enum.html
저작자 표시 비영리 동일 조건 변경 허락
신고

'윈도우 > 스터디' 카테고리의 다른 글

DLL (Dynamic Link Library) 정리  (0) 2012.01.16
Media Transfer Protocol (MTP)  (0) 2011.12.15
PostThreadMessage로 SendThreadMessage 구현하기  (0) 2011.11.28
_stprintf_s  (0) 2011.11.28
Visual Studio C++ 메모리 릭  (2) 2011.11.24
posted by Town One townone
2011.11.28 18:43 윈도우/스터디

스레드에서 메시지 처리를 하는 경우 스레드에서 특별히 윈도우를 만들지 않는 이상 PostThreadMessage 밖에 메시지를 보낼 수 있는 방법이 없다.


특별한 경우 SendThreadMessage 같은 걸 사용하고 싶은 경우 Event 객체를 써서 비슷하게 구현할 수 있다.

메시지 전송 부분

enum ThreadMessageFlag { TMF_ASYNC=0, TMF_SYNC };

HANDLE waitMsg = CreateEvent(NULL, TRUE, FALSE, NULL);

if(PostThreadMessage(threadId_, WM_THREAD_INITIALIZE, reinterpret_cast<WPARAM>(waitMsg), TMF_SYNC)) {
if(WaitForSingleObject(waitMsg, MSG_TIMEOUT) != WAIT_OBJECT_0) {
CloseHandle(waitMsg);
return false;
}
}
CloseHandle(waitMsg);
return true;

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


메시지 받는 부분

// 메시지 처리
...
// 메시지 동기화
if(lParam == TMF_SYNC) {
HANDLE waitMsg = reinterpret_cast<HANDLE>(wParam);
SetEvent(waitMsg);
}
return;

메시지 전송 부분에서 MSG_TIMEOUT 을 INFINITE로 하면 SendMessage와 비슷하게 되고 시간을 설정하게 되면 SendMessageTimeOut 형태로 구현할 수 있게 된다.
INFINITE 로 대기하게 되는 경우 데드락이 발생할 수 있으니 메시지를 받는 부분에서 이벤트 처리를 확실하게 해야 한다.


신고

'윈도우 > 스터디' 카테고리의 다른 글

DLL (Dynamic Link Library) 정리  (0) 2012.01.16
Media Transfer Protocol (MTP)  (0) 2011.12.15
PostThreadMessage로 SendThreadMessage 구현하기  (0) 2011.11.28
_stprintf_s  (0) 2011.11.28
Visual Studio C++ 메모리 릭  (2) 2011.11.24
posted by Town One townone
2011.11.28 16:18 윈도우/스터디
    static TCHAR buffer[16];    
    _stprintf_s(buffer, sizeof(buffer)/sizeof(TCHAR), _T("[%d]"), index);

_stprintf_s 함수는  _stprintf 함수에서 버퍼 오버플로우를 방지하기 위하여 메모리 사이즈 만큼만 입력 될수 있도록 제한 한 함 수이다.

되도록 safe 함수를 이용 하도록 하자.
신고

'윈도우 > 스터디' 카테고리의 다른 글

DLL (Dynamic Link Library) 정리  (0) 2012.01.16
Media Transfer Protocol (MTP)  (0) 2011.12.15
PostThreadMessage로 SendThreadMessage 구현하기  (0) 2011.11.28
_stprintf_s  (0) 2011.11.28
Visual Studio C++ 메모리 릭  (2) 2011.11.24
posted by Town One townone
2011.11.24 10:04 윈도우/스터디


Visual Studio 출력 창에 메모리 릭이 표시 된다. 예제 프로그램으로 간단히 정리 한다.
MFC 프로젝트를 이용하는 경우, 소스 위쪽에

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

위 코드를 추가하여 메모리 릭 위치를 추적 할 수 있다. 콘솔 프로그램인 경우 아래와 같이 한다.

1) 예제 프로그램 - 콘솔 응용 프로그램

// MemoryLeakTest.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"

// 콘솔 프로젝트에서 메모리릭 정보가 출력 창에 출력될 수 있도록 추가
#include <crtdbg.h>


int _tmain(int argc, _TCHAR* argv[])
{
 // 콘솔 프로젝트에서 메모리릭 정보가 출력 창에 출력될 수 있도록 추가
 _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

 int *nData = new int;

 return 0;
}

출력 값은 아래와 같다.

'MemoryLeakTest.exe': 'F:\Data\Study\MemoryLeakTest\Debug\MemoryLeakTest.exe' 로드, 기호가 로드되었습니다.
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\ntdll.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\kernel32.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\KernelBase.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_2a4f639a55563668\msvcr90d.dll' 로드, 기호가 로드되었습니다.
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\apphelp.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\apphelp.dll' 언로드
Detected memory leaks!
Dumping objects ->
{116} normal block at 0x00698680, 4 bytes long.
 Data: <    > CD CD CD CD
Object dump complete.
'[2120] MemoryLeakTest.exe: 네이티브' 프로그램이 종료되었습니다(코드: 0 (0x0)).


{116} normal block at 0x00698680, 4 bytes long.
여기서 {116}은 메모리 생성 순서이다. 116번째 메모리 생성시 브레이크 포인트를 건다.

// MemoryLeakTest.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"

// 콘솔 프로젝트에서 메모리릭 정보가 출력 창에 출력될 수 있도록 추가
#include <crtdbg.h>


int _tmain(int argc, _TCHAR* argv[])
{
 _CrtSetBreakAlloc(116); // 116 번째 메모리 생성시 프레이크 걸리도록 추가

 // 콘솔 프로젝트에서 메모리릭 정보가 출력 창에 출력될 수 있도록 추가
 _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

 int *nData = new int;

 return 0;
}

실행 시키면 아래와 같이 중단점이 트리거 된다.


중단을 누르고 호출 스택을 보면 아래와 같다.

호출 스택에서 해당 위치로 가면 아래와 같이 메모리릭 발생 지점을 가리킨다.

하지만 프로그램이 크고 여러 모듈들이 비순서 적으로 로딩 되면 메번 실행시마다 생성되는 메모리 순서가 바뀌게 됩니다.

// MemoryLeakTest.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"

// 참고 : http://support.microsoft.com/kb/601929/ko

// 콘솔 프로젝트에서 메모리릭 정보가 출력 창에 출력될 수 있도록 추가
// 디버그 빌드 메모리 함수를 이용하여야 릭 표시시 파일이름이 표시된다.
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>

int _tmain(int argc, _TCHAR *argv[])
{
 //_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
 int *nData = (int*) malloc(16);

 _CrtDumpMemoryLeaks( );
 return 0;
}

위와 같이 Define 을 추가하면 아래와 같이 해당 위치가 표시된다.

'MemoryLeakTest.exe': 'F:\Data\Study\MemoryLeakTest\Debug\MemoryLeakTest.exe' 로드, 기호가 로드되었습니다.
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\ntdll.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\kernel32.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\KernelBase.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_2a4f639a55563668\msvcr90d.dll' 로드, 기호가 로드되었습니다.
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\apphelp.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\apphelp.dll' 언로드
Detected memory leaks!
Dumping objects ->
f:\data\study\memoryleaktest\memoryleaktest.cpp(16) : {116} normal block at 0x00418680, 16 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
'[3892] MemoryLeakTest.exe: 네이티브' 프로그램이 종료되었습니다(코드: 0 (0x0)).

더블 클릭 하여 해당 위치로 찾아간다.

신고

'윈도우 > 스터디' 카테고리의 다른 글

DLL (Dynamic Link Library) 정리  (0) 2012.01.16
Media Transfer Protocol (MTP)  (0) 2011.12.15
PostThreadMessage로 SendThreadMessage 구현하기  (0) 2011.11.28
_stprintf_s  (0) 2011.11.28
Visual Studio C++ 메모리 릭  (2) 2011.11.24
posted by Town One townone

티스토리 툴바