정적 라이브러리와 동적 라이브러리에 대한 설명은 다른 링크를 참고해주세요.
확장 DLL 만드는법에 대한 설명은 여기를 참조해주세요.
정적 DLL을 만들어 보겠습니다.
새 프로젝트 -> MFC -> MFC DLL을 선택하셔서 프로젝트를 생성해 줍니다.
“MFC를 정적으로 링크한 기본 DLL”을 선택하시고 마침을 눌러줍니다.
그러면 아래와 같이 프로젝트 하나 생성됩니다.
CMFCLibrary1App에 간단한 더하기 함수 int SumXY(int iX, int iY); 를 추가해 줍니다.
// MFCLibrary1App.h int SumXY( int iX, int iY );
// MFCLibrary1App.cpp int CMFCLibrary1App::SumXY( int iX, int iY ) { return iX + iY; }
MFCLibrary1App.h에 CMFCLibrary1App 클래스 외부에 extern 변수를 선언합니다. 이렇게 하면 외부에서 라이브러리를 로드 할 수 있습니다. 아래 하이라이트 부분처럼 입력합니다.
class CMFCLibrary1App : public CWinApp { public: CMFCLibrary1App(); // 재정의입니다. public: virtual BOOL InitInstance(); DECLARE_MESSAGE_MAP() public: int SumXY( int iX, int iY ); }; extern CMFCLibrary1App theApp;
theApp이라는 변수는 MFCLibrary1App.cpp 파일에 보시면 생성할 때부터 선언되어있던 변수입니다.
아래 그림과 같이 API 헤더파일과 .cpp 파일을 만들어 줍니다.
각각의 MFCLibraryAPI.h와 .cpp 파일에 아래와 같이 코딩합니다.
// MFCLibraryAPI.h #pragma once #ifdef _MATH_API_ #define MATH_API extern "C" __declspec(dllexport) #else #define MATH_API extern "C" __declspec(dllimport) #endif MATH_API int API_SumXY( int iX, int iY );
// MFCLibraryAPI.cpp #pragma once #include"pch.h"; #define _MATH_API_ #include "MFCLibraryAPI.h"; #include "MFCLibrary1.h"; MATH_API int API_SumXY( int iX, int iY ) { return theApp.SumXY( iX, iY ); }
이제 대화상자에서 만든 라이브러리를 사용해야겠죠? 솔루션 우클릭 -> 추가 -> 새 프로젝트를 선택해 줍니다.
MFC -> MFC 응용 프로그램을 선택하여 대화상자 기반으로 만들어 줍니다.
대화상자의 헤더파일에 아래와 같이 함수 타입을 만들어 줍니다.
DECLARE_MESSAGE_MAP() public: HMODULE m_hModule; typedef int(*FN_API_SumXY)(int iX, int iY ); FN_API_SumXY m_fn_API_SumXY; afx_msg void OnBnClickedOk(); afx_msg void OnBnClickedCancel(); };
OnInitDialog에 아래와 같이 라이브러리를 로드하는 구문을 입력합니다.
CString sDll = _T( ".\\MFCLibrary1.dll" ); m_hModule = ::LoadLibrary( sDll ); if ( NULL != m_hModule ) { m_fn_API_SumXY = (FN_API_SumXY)::GetProcAddress( m_hModule, "API_SumXY" ); if ( NULL != m_fn_API_SumXY ) { int iSum = m_fn_API_SumXY( 2, 3 ); CString sMsg; sMsg.Format( _T("%d"), iSum ); AfxMessageBox( sMsg ); } else { AfxMessageBox( _T( "Function Open Error" ) ); } } else { AfxMessageBox( _T( "Dll Open Error" ) ); }
실행시켜서 작동 되나 확인해 봅니다.
확장 DLL과 몇가지 차이가 있는데 실무하면서 느꼈던 제일 큰 차이는
- 확장 DLL은 실행 파일과 같은 위치에 없으면 dll을 로드하는 프로세스는 실행 자체가 안되고, 정적 DLL 실행은 됩니다. 로드만 실패합니다.
- Visual Studio MFC가 설치되어 있지 않은 프로그램에서 확장 DLL을 로드하는 프로그램을 실행하면 MFC DLL이 없다고 에러납니다. (mfc1004.dll이였나.. 기억이 가물하네요). 이경우에는 Visual C++ 재배포 패키지를 설치하거나 Visual Studio 설치 위치 뒤져서 dll을 찾아서 같은 실행 폴더에 놓아야 합니다.
정적 DLL은 그럴 필요 없습니다. 정확한 차이와 개념은 검색해서 공부하시길 추천합니다.