1.정적링크 라이브러리와 동적링크 라이브러리
- 정적링크 라이브러리: 프로그램에서 호출한 라이브러리의 함수 코드가 실행 파일안으로 복사되어 만들어진다.
- 동적링크 라이브러리: 실행화일을 만들때 라이브러리에서 사용한 함수에 대한 정보만을 복사하고 함수가 실제
실행되는 시점에 라이브러리가 메모리에 로드된다.
2. DLL이란
실행시에 로드되고 링크 될 수 있는 윈도우즈 프로그램의 기본 모듈이다.
3. DLL의 장점
- 메모리를 절약할 수 있고 스와핑을 줄일 수 있다.
- 디스크 용량을 줄일 수 있다.
- 프로그램 실행속도가 빨라진다.
- DLL을 업그레이드 하기가 쉽다.
-여러가지 프로그램언어로 된 응용 프로그램을 지원한다.
-리소스 교체가 가능하다.
-프로젝트 관리가 용이하다.
4. DLL의 단점
-프로그램 배포시 해당 DLL을 함께 배포 해야 한다.
5. MFC와 DLL
DLL파일(D는 Debug모드) 기능
=================================== ========================================
MFC42.DLL( MFC42D.DLL ) 기본적인 MFC 클래스들
MFCO42.DLL( MFCO42D.DLL ) OLE 관련 클래스들
MFCD42.DLL( MFCD42D.DLL ) ODBC 관련 클래스들
MFCN42.DLL( MFCN42D.DLL ) 네트워크 관련 클래스들
MSVCRT.DLL( MSVCRTD.DLL ) C run-time library
----------------------------------------------------------------------------
6.MFC를 사용하는 DLL의 종류
-Regular DLL with MFC statically linked : 자신이 만든 DLL에 MFC관련 DLL이 포함된다. 다른 응용 프로그램에서 이용가능
-Regular DLL using shared MFC DLL : 자신이 만든 DLL에 MFC관련 DLL이 포함되지 않는다.다른 응용 프로그램에서 이용가능
-MFC Extension DLL using shared MFC DLL : 자신이 만든 DLL에 MFC관련 DLL이 포함되지 않는 DLL로 MFC로 만든
응용프로그램에서만 사용가능.
7. 임포트 함수와 엑스포트 함수
임포트함수 : extern "C" __declspec(dllimport) 리터형 함수명(매개변수,...) ;
- 메인프로그램에서 DLL에 있는 함수를 호출할때 사용한다.
엑스포트함수 : extern "C" __declspec(dllexport) 리터형 함수명(매개변수,...)
{
내용;
}
- DLL에서 정의되는 것으로 다른 DLL이나 메인 프로그램에서 가져갈 수 있도록 허용하는 함수이다.
8. 실행화일과 DLL을 연결하는 방법
1) 암시적 연결
-실행화일을 생성할때 DLL제공자가 만들어준 임포트 라이브러리를 사용하여 링크한다. 응용프로그램이 로드될때
임포트 라이브러리를 참조하여 DLL도 같이 로드된다.
-DLL과 암시적으로 연결할 때
* 해당 DLL파일이 있어야 한다.
* 함수 선언을 해주는 헤더화일이 있어야 한다.
* 함수정보를 가지고 있는 임포트 라이브러리 화일이 있어야 한다.(*.LIB)
2) 명시적 연결
-실행 시간에 직접 DLL을 로드하는 방법이다.
-DLL을 메모리에 로드하려 할때 윈도우즈는 KERNEL32.DLL 와 USER32.DLL등 미리 인스톨된 DLL에서 다음과 같은 순서로 찾는다.
* 실행화일이 있는 현 디렉토리
* Windows\System 디렉토리
* Windows 디렉토리
* Path로 지정된 디렉토리
# 다이알로그를 띄울때는 부모윈도우 포인터를 주어야 합니다.
예)
extern "C" __declspec(dllexport) BOOL ShowLogin( LPSTR user, LPSTR pass)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CWnd *pWnd=AfxGetMainWnd();
CLoginDlg dlg(pWnd);
dlg.m_user=user;
if( dlg.DoModal()==IDOK)
{
strcpy(user, dlg.m_user);
strcpy(pass, dlg.m_pass);
return TRUE;
}
else
return FALSE;
}
예제) DLL 프로그램 만들기
1) MFC AppWizard(DLL)를 이용하여 프로젝트를 생성한다.
2) 다이알로그 박스등을 만들어 해당 프로그램을 만든다.
3) 외부에서 참조할 엑스포트 함수를 작성한다.
extern "C" _ _declspec(dllexport)
BOOL ShowLoginDlg(LPSTR userID, LPSTR password)
{
}
4) 엑스포트 함수의 원형을 제공하는 헤더 파일을 작성한다.
// login.h
extern "C" _ _declspec(dllimport)
BOOL ShowLoginDlg(LPSTR userID, LPSTR password);
5) 컴파일하여 DLL을 생성한다.
예제) 실행 화일과 DLL을 연결하는 방법
1) 암시적 연결
-DLL화일과 헤더화일(*.h) ,라이브러리 화일(*.LIB)을 가져온다.
-메인 프로젝트를 생성한다.
-작업 디렉토리에 헤더화일(*.h)을 복사한다.
-Debug 폴더에 DLL과 LIB화일을 복사한다.
-메인 프로그램에 해당 DLL을 호출할 수 있는 프로그램을 작성하고 헤더화일(*.h)을 include 시킨다.
BOOL CTestApp::InitInstance()
{
char user[21]="chang";
char pass[21];
if(ShowLoginDialog(user,pass)==TRUE)
{
CString str;
str.Format("user=%s \n pass=%s",user,pass);
AfxMessageBox(str);
}
ShowDlg();
}
-프로젝트의 Settingsㅇ의 Link탭에서 Object/Library modules 에 import 라이브러리를 지정한다.
(여러개 지정시 공백으로 구분한다) 예) C:\vc\test\debug\login.lib
2) 명시적 연결
BOOL CTest1App::InitInstance()
{
char user[20]="chang";
char pass[20];
BOOL (*pfn)(LPSTR,LPSTR); //함수포인터
HINSTANCE hins;
if((hins=LoadLibrary("changFun.dll"))==NULL)
{ AfxMessageBox("changFun.dll 화일을 로드할 수 없다");
return ;
}
pfn=(BOOL(*)(LPSTR,LPSTR)) GetProcAddress(hins,"ShowLogin");
if(pfn==NULL)
{ AfxMessageBox("ShowLogin function을 로드할 수 없습니다");
return;
}
if( pfn(user,pass)==TRUE)
{
CString str;
str.Format("%s %s",user,pass);
AfxMessageBox(str);
}
else
{
AfxMessageBox("접속 불가");
return FALSE;
}
FreeLibrary(hins);
}
[클래스 내의 아무 cpp에 추가]
1.로그인 다이얼로그를 만들고 (login.cpp)
2.로긴app에서 외부에서 사용하는 다이얼로그 부르는 함수를 써주고,
#include "LoginDlg.h"
extern "C" __declspec(dllexport) BOOL ShowLogin(LPSTR user, LPSTR pass)
{
CLoginDlg dlg;
dlg.m_user = user;
if (dlg.DoModal() == IDOK) {
strcpy(user, dlg.m_user);
strcpy(pass, dlg.m_pass);
return TRUE;
}
else {
return FALSE;
}
}
2.테스트할 프로젝트를 만들어
. 메뉴에서 로그인 함수 부르는 처리
extern "C" __declspec(dllimport) BOOL ShowLogin(LPSTR, LPSTR);
void CDlltest1View::OnLoginDlg()
{
// TODO: Add your command handler code here
char name[20] = "홍길동";
char pass[20];
BOOL bCheck = ShowLogin(name,pass);
if (bCheck) {
CString str;
str.Format("사용자: %s \n암 호:%s 님의 접속을 검사합니다.", name,pass);
MessageBox(str,"접속");
}
else {
MessageBox("접속을 거부합니다.","취소");
}
}
만든 .DLL과 .LIB를 테스트 실행파일이 있는 곳에 COPY후
메뉴 Project-Setting-Link에 Object/Library Module란에 Debug/hsjeon.lib를 써준다.
extern "C" __declspec(dllimport) BOOL ShowLogin(LPSTR, LPSTR);
void CDlltest1View::OnLoginDlg()
{
// TODO: Add your command handler code here
char name[20] = "홍길동";
char pass[20];
BOOL bCheck = ShowLogin(name,pass);
if (bCheck) {
CString str;
str.Format("사용자: %s \n암 호:%s 님의 접속을 검사합니다.", name,pass);
MessageBox(str,"접속");
}
else {
MessageBox("접속을 거부합니다.","취소");
}
}
로그인을 실행하면서 뜨게 하려면 CDlltest1App::InitInstance 에 로긴창을 띄우는 것을
BOOL CDlltest1App::InitInstance()
{
AfxEnableControlContainer();
char name[20] = "홍길동";
char pass[20];
BOOL bCheck = ShowLogin(name,pass);
if (bCheck) {
CString str;
str.Format("사용자: %s \n암 호:%s 님의 접속을 검사합니다.", name,pass);
MessageBox(str,"접속");
}
else {
MessageBox("접속을 거부합니다.","취소");
return FALSE;
}
선언을 cpp마다 하기가 .. 그래서 .H로 만들어 INCLUDE 해서 사용할 수 있다.
extern "C" __declspec(dllimport) void ShowCal();
extern "C" __declspec(dllimport) BOOL ShowLogin(LPSTR, LPSTR);
int a;
int *p;
p = &a;
k = aa(10,5);
int (*)q; //함수포인터
q = aa;
k = q(10,5);
[명시적dll연결]
void CDlltest2View::OnLoginDlg()
{
// TODO: Add your command handler code here
// TODO: Add your command handler code here
HINSTANCE hinst = LoadLibrary("hsjeon.dll");
if (hinst == NULL) {
AfxMessageBox("hsjeon.dll이 없습니다.");
return;
}
BOOL (*pFn)(LPSTR, LPSTR);
pFn = (BOOL (*)(LPSTR,LPSTR))GetProcAddress(hinst,"ShowLogin");
if (pFn == NULL) {
AfxMessageBox("ShowLogin함수가 없습니다.");
FreeLibrary(hinst);
return;
}
char name[20] = "홍길동";
char pass[20];
BOOL bCheck = pFn(name,pass);
if (bCheck) {
CString str;
str.Format("이름:%s 암호:%s 님이 로그온 했습니다.", name,pass);
AfxMessageBox(str);
}
else {
AfxMessageBox("로그온 할 수 없습니다.");
}
FreeLibrary(hinst);
}
void CDlltest2View::OnCalDlg()
{
HINSTANCE hinst = LoadLibrary("hsjeon.dll");
if (hinst == NULL) {
AfxMessageBox("hsjeon.dll이 없습니다.");
return;
}
void (*pFunct)();
pFunct = (void (*)())GetProcAddress(hinst, "ShowCal");
if (pFunct == NULL) {
AfxMessageBox("ShowCal함수가 없습니다.");
FreeLibrary(hinst);
return;
}
pFunct();
FreeLibrary(hinst);
}
dll만들때 shared로 하려면
AFX_MANAGE_STATE(AfxGetStaticModuleState());을 넣어준다.
그리고 dlg 인스턴스화 할때
CWnd *pWnd=AfxGetMainWnd();를 준다.
CLoginDlg dlg(pWnd);
extern "C" __declspec(dllexport) BOOL ShowLogin(LPSTR user, LPSTR pass)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CWnd *pWnd=AfxGetMainWnd();
CLoginDlg dlg(pWnd);
;
dlg.m_user = user;
...
}
int division(int x, int y);
void main() //int division();
ptr_int = division;
value= (*ptr_int)(a, b);
printf("%d / %d = %d",a,b,value);
int division(int x,int y) |
'□컴퓨터 관련 > ☆C, C++' 카테고리의 다른 글
[Batch] 해당 폴더 내 특정 파일 검색하기 (2) | 2016.11.17 |
---|---|
GetLastError() Return Value [펌] (0) | 2011.02.23 |
warning c4996 strcpy deprecated (0) | 2011.02.11 |
#pragma란? (2) | 2010.04.07 |
데브피아 (3) | 2010.02.08 |
매트랩 기본 (0) | 2008.10.07 |
비트연산 (0) | 2008.10.02 |