[DLL] dll import하기

1.export 를 클래스 또는 구조체 단위로 하였을때

2.export 를 함수 단위로 하였을 때



필요한 dll, lib 파일 모두 이동 후!!!


    1. #pragma comment(lib, "~~.lib") 혹은  속성에서 lib 파일을 포함 
    2. 클래스,구조체가 선언되어 있는 헤더 파일을 dll을 import 할 프로젝트에 추가
    3. 사용
  1.  
    1. #pragma comment(lib, "~~.lib") 혹은  속성에서 lib 파일을 포함
    2. 헤더파일 생성
    3. export한 함수들 선언
      1. __declspec(dllimport) void TEST (void* cd);
      2. 주의할 점은 dll에서 함수를 선언한 방법과 동일하게 
        1. __declspec(dllimport) => __declspec(dllimport)
        2. extern "C" __declspec(dllimport) => extern "C" __declspec(dllimport) 


[winapi] 파일 선택 다이얼로그 띄우기

- 함수 원형


BOOL fnBrowseFolder( HWND hWnd, const char *pTitle, char *pFolder, UINT nFlags )

{

LPMALLOC pMalloc;

LPITEMIDLIST pidl;

BROWSEINFO bi;


memset( &bi, 0, sizeof( BROWSEINFO ) );

bi.hwndOwner = hWnd;

bi.pidlRoot = NULL;

bi.pszDisplayName = NULL;

bi.lpszTitle = (char *)pTitle;

bi.ulFlags = nFlags;

bi.lpfn = NULL;

bi.lParam = 0;


pidl = SHBrowseForFolder( &bi );


if( pidl == NULL )

return FALSE;


SHGetPathFromIDList( pidl, pFolder );


if( SHGetMalloc( &pMalloc ) != NOERROR )

return FALSE;


pMalloc->Free(pidl);

pMalloc->Release();


return TRUE;

}


- 사용 시 

if( !fnBrowseFolder( hWnd, "디렉토리 또는 드라이브를 선택해주세요.",Path, BIF_RETURNONLYFSDIRS ) ) 

MessageBox(hWnd,"오류!",NULL,MB_OK);



Path에 선택한 파일 경로가 저장 된다.

[winapi]OWNER DRAW로 여러 버튼 그려주기

버튼 선택 후 클릭 상태 유지 &  다른 버튼 클릭 시 버튼 다시 그려줌 

InvalidateRect()는 WM_PAINT 뿐만 아니라 WM_DRAWITEM도 호출한당




case WM_DRAWITEM:

lpdis = (LPDRAWITEMSTRUCT)lParam;

memDC=CreateCompatibleDC(lpdis->hDC);


switch(lpdis->CtlID)

{

case IDC_BUTTON1:

if(lpdis->itemState & ODS_SELECTED || nDownTab == 1)

SelectObject(memDC, hBitmapDown[0]);

else

SelectObject(memDC, hBitmap[0]);

break;


case IDC_BUTTON2:

if(lpdis->itemState & ODS_SELECTED || nDownTab == 2)

SelectObject(memDC, hBitmapDown[1]);

else

SelectObject(memDC, hBitmap[1]);

break;

}

BitBlt(lpdis->hDC,0,0,150,140,memDC, 0,0,SRCCOPY);

DeleteDC(memDC);

break;




버튼 클릭 시 설정 해주는 부분

case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_BUTTON1:
// 다이얼로그 생성
InvalidateRect( hDlg, &rt, false ); 
nDownTab = 1;
break;

case IDC_BUTTON2:
// 다이얼로그 생성
InvalidateRect(hDlg,&rt, false ); 
if(nDownTab == 2)
break;
break;
}
break;

다이얼 로그 초기화 부분에서 버튼 크기의 RECT 설정 후 
버튼 누를때마다 버튼 부분 다시 그려줌 

SetRect(&rt,0,35,120,300);


디렉토리 파일 개수 구하기(하위 디렉토리 포함 )

디렉토리의 하위 파일 개수까지 구함 


int countFile(char* Path)

{

HANDLE hSrch;


WIN32_FIND_DATA wfd;

BOOL bResult = TRUE;


char newpath[MAX_PATH];


char drive[_MAX_DRIVE];

char dir[MAX_PATH];

char ext[_MAX_EXT] = {0,};

hSrch=FindFirstFile(Path, &wfd);

while(bResult)

{

_splitpath(Path,drive,dir,NULL,ext);


if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)

{


if(wfd.cFileName[0] != '.')

{

wsprintf(newpath,"%s%s%s\\*.*",drive,dir,wfd.cFileName);

countFile(newpath);

}

}else fileCnt++;


bResult = FindNextFile(hSrch, &wfd);

}

FindClose(hSrch);

return fileCnt;

}


'c/c++' 카테고리의 다른 글

static 정적 변수 정리  (0) 2012.12.18
[DLL] dll import하기  (0) 2012.12.17
[LNK 2001] DLL 포함 시키기  (0) 2012.12.04
프로그램 중복 실행 방지 (뮤텍스 사용)  (0) 2012.11.22
디버그 화면 릴리즈 파일출력  (0) 2012.11.22

[LNK 2001] DLL 포함 시키기

0. dll, lib 파일 적용 시키려는 프로젝트에 저장


1. 속성 페이지

[구성 속성] - [링커] - [입력] 

에서

추가 종속성에 lib 파일 추가


2. 사용하려는 함수가 들어있는헤더 파일 추가


3. 헤더 파일 위에 

#pragma comment(lib, "~~~.lib")

추가



을 잘 해주었는데도 LNK2001 에러가 발생한다면 

디버그 버전 DLL, lib 파일을 추가 하였는지 검사 할 것

왜 디버그로 빌드한 dll을 포함시키면 에러남?ㅜㅜㅜㅜㅜㅜ


릴리즈 버전으로 dll, lib 생성하여 추가하기!

 

HINSTANCE HWND 차이

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


HINSTANCE 핸들은 보통 실행되고 있는 Win32 프로그램이

메모리 상에 올라가 있는 시작 주소 값을 갖고 잇습니다.

보통은 0x00400000 이런식의 값을 가지고 있는데 저 값의

메모리 주소에 실행 모듈이 올라가 잇다는 것을 의미 하겠죠.

보통 리소스들을 로드 하는 함수들에서 이 핸들 값을 많이

참조하게 되는데 이 이유는 메모리 상에 올라가 있는 실행 모듈 들중

(exe, dll 등등.. ) hInstance 가 가르키는 주소에 올라가 있는 실행

모듈에서 그 리소스를 읽어 오라고 지정 해주는 것입니다.

이 외에 GetProcAddress() 같이 다른 DLL 에서 함수 주소를

얻어야 하는 경우에도 HMODULE ( Win32 에선 HINSTANCE 와

동일한 기능을 하고 같은 값이라고 보시면 됩니다.) 와 같이 메모리

상에 올라가 있는 어느 특정 모듈을 가르킬때 사용하게 됩니다.

그리고 그 변수를 글로벌로 잡는 경우가 있는데 그 이유는 그 변수를

여러 함수들에서 자주 사용하기 때문에 Win32의 구현 방식상 여러

함수에서 그 값을 읽어 와야 하고 그 값은 WinMain() 에서 한번 들어

오는 값이기 때문에 글로벌 변수에 넣어 두는것이죠...

물론 C++ 클래스로 MFC 처럼 하여 꼭 글로벌로 두지 않아도 되게 하는

방법도 있습니다만.. 어떤 방식이던 목적은 같습니다. 

참고하세요 ^^


////////////////////////////////////////////////////////////////

 

HINSTANCE는 프로그램의 인스턴스 식별자(핸들)을 의미합니다.

간단히 말씀드리자면 실행파일 형태로 껍데기에 불과한 프로그램이 메모리에 실제로

구현된 실체를 뜻합니다.

따라서 만약에 프로그램을 여러개 실행시켰을 때 이들의 각각을 프로그램 인스턴스라고

 하고 실행되는 프로그램마다 고유한 값을 갖고

실행중인 프로그램들을 구분하기 위한 식별값으로 인스턴스 핸들을 이용합니다.

 

HWND는 프로그램의 윈도우 식별자(핸들)를 의미하는데 해당 프로그램의 윈도우들을

구분하기 위한 식별 값을 말합니다. 여기서 윈도우와 프로그램과는 차이가 있습니다.

윈도우 프로그래밍에서 하나의 프로그램에는 많은 윈도우들을 가질수 있기 때문입니다.

프로그램의 윈도우 핸들 중에서 대표적인 것이 부모 윈도우의 핸들입니다. 따라서 대부분의

윈도우 프로그래밍의 작업과정중 대부분은 이들 HWND 값을 통해 얻은 윈도우 핸들을

이용한다고 이해하시면 빠를꺼 같습니다. 창뿐만 아니라 여러가지 수많은 컨트롤 등도 모두

윈도우로 생성시에 핸들값을 소유하고 있는 존재이기 때문입니다.

------------------------------------------------------------------------------------

 

HINSTANCE는 프로그램의 핸들이 아니라, 프로그램 코드를 담고 있는 모듈에 대한 핸들이다. 즉, 프로그램이 수행되려면 프로그램 코드를 담고 있는 파일을 메모리의 특정 영역에 올려서 명령을 하나식 읽어가면서 수행할 수 있도록 준비해 놓아야 한다.

 

이렇게메모리에 올려진 프로그램 코드 덩어리를 윈도우에서 관리하기 위해서 일종의 고유 식별 번호를 부여하는데, 이것이 인스턴스 핸들, HINSTANCE이다. 기본적으로 프로세스를 실행하는 실행파일의 코드를 메모리에 올려놓은 모듈이 하나 있어야 하므로, 실행 파일의 모듈에 대한 인스턴스 핸들을 OS가 어플리케이션 WindMain의 인자로 넘겨주는 것이다.

 

한 프로세스가 여러개의 모듈을 로딩하여 프로그램을 실행하고 있다면 하나의 프로그램이 여러개의 인스턴스 핸들을 할당받아 쓰고 있을 수 있다.(물론 한 개의 모듈을 여러 프로세스가 공유하고 있을 수도 있다.) 대표적인 예가 바로 IE인데, 간단하게 DLL파일 한 개를 쓸 때마다 이 DLL 모듈에 대한 인스턴스 핸들이 한 개씩 생긴다고 보면 된다. 물론 DLL이 한번 로딩되면 다른 프로그램 사이에서 공유된다.

 

한 개의 프로그램에서 HINSTANCE가 한 개만 있는 것이 아니며, 또한 하나의 인스턴스 핸들이 한 개의 프로그램에만 종속되는 것이 아니므로 어떤 프로그램의 출력 대상을 지정하는 데에는 부적적하다는 점을 알 수 있다. 물론, 인스턴스 핸들은 애초부터 화면 출력을 고려햐여 만들어진 식별자는 아니며 단지 프로그램 코드 덩어리를 관리하기 위해 만들어진 리소스이다.

 

윈도우라는 OS에서 화면 출력을 위해 관리하는 리소스가 바로 HWND이다. MSN 메신저 등을 보면 알겠지만 하나의 프로그램이 하나의 창을 사용한다는 보장은 없다. 오히려 99.99%의 프로그램은 한 개 이상의 윈도우로 구성되어 있다. 한 프로그램의 윈도우가 겉보기에는 단일한 대상 영역으로 보일지라도 실제로는 구성요소별로 분리하여 별개의 윈도우로 만들어 각 윈도우는 자기 자신이 맡은 부분에 대한 화면 출력과 사용자 입력만을 담당한다. 자연히 하나의 프로그램에서 사용하는 HWND 타입의 개체 역시 1개 이상이 될 수 밖에 없으며, 이러한 상황에서 특정 위치에 특정한 동작을 수행하기 위해서는 HWND로 대상 영역을 구분할 수 밖에 없다.

 

------------------------------------------------------------------------------------

 

HWND와 HINSTANCE의 구조체 내용을 보시면 가지는 속성들이 전혀 다릅니다.

HWND는 윈도우 자체에 대한 정보를 가지는 것이고,
HINSTANCE는 현재 실행중인 인스턴스에 관한 정보를 가지고 있습니다.
인스턴스는 운영체제 전체에서 유일한 번호를 가지므로(실행중인 창들이라고 보면되죠)
HWND를 가지고 인스턴스를 구할순 없지만 HINSTANCE를 가지고 있으면
HWND에 관한 내용들을 구할수 있습니다.

프로그램 중복 실행 방지 (뮤텍스 사용)

HANDLE   g_hDupMutex;

g_hDupMutex = CreateMutex(NULL, false, __APP_TITLE);
if (GetLastError() == ERROR_ALREADY_EXISTS) 
{  
  return -1;
}

//종료 시
if( g_hDupMutex )
{
  CloseHandle( g_hDupMutex );
  g_hDupMutex = 0;  
}

디버그 화면 릴리즈 파일출력

//디버그 일때 콘솔 출력 릴리즈 일때는 파일 출력 

void wprintd (const wchar_t* format, ...)

{

FILE* fp = stdout;


#ifdef NDEBUG

fp = fopen (DEBUGFILE, "a");

if (fp == 0)

return;

#endif 


va_list arg;

va_start (arg, format);

vfwprintf (fp, format, arg);

va_end (arg);


#ifdef NDEBUG

fclose (fp);

#endif 

}


스레드 생성 - 생성하려는 함수 파라미터가 여러개 일때

  #include <iostream>
 #include <windows.h>
 using namespace std;

 void Func(LPVOID pArgs_);

 struct ARGS {
   int *i;
   double d;
 };

 int main()
 {
   DWORD ThreadID;
   int x=1;
   double y=5.23;
   ARGS args = { &x, y };
   HANDLE hThread=CreateThread(0,0,(LPTHREAD_START_ROUTINE)Func,&args,0,&ThreadID);
	 WaitForSingleObject(hThread,INFINITE);
	 return 0;
 }


 void Func(LPVOID pArgs_)
 {
   ARGS *pArgs = (ARGS*)pArgs_;
   cout<<"Values are: "<<*pArgs->i<<" i "<<pArgs->d<<endl;
 } 

'c/c++' 카테고리의 다른 글

프로그램 중복 실행 방지 (뮤텍스 사용)  (0) 2012.11.22
디버그 화면 릴리즈 파일출력  (0) 2012.11.22
시간, 날짜 가져오기  (0) 2012.11.22
쓰레드  (0) 2012.11.21
MMF  (0) 2012.11.16

시간, 날짜 가져오기

LPCWSTR GetDate(char* c) 

{ SYSTEMTIME systemTime;

GetLocalTime(&systemTime);

COleDateTime dateTime(systemTime);


if(strcmp(c, "Time") == 0)

return dateTime.Format(L"%X");

else if(strcmp(c, "Date") == 0)

return dateTime.Format(L"%x");

else

return dateTime.Format(L"%c");

}

'c/c++' 카테고리의 다른 글

디버그 화면 릴리즈 파일출력  (0) 2012.11.22
스레드 생성 - 생성하려는 함수 파라미터가 여러개 일때  (0) 2012.11.22
쓰레드  (0) 2012.11.21
MMF  (0) 2012.11.16
디버그 창에 출력하기  (0) 2012.11.16