[MFC] Static DLL(정적 DLL) 만들기

정적 라이브러리와 동적 라이브러리에 대한 설명은 다른 링크를 참고해주세요.

확장 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과 몇가지 차이가 있는데 실무하면서 느꼈던 제일 큰 차이는

  1. 확장 DLL은 실행 파일과 같은 위치에 없으면 dll을 로드하는 프로세스는 실행 자체가 안되고, 정적 DLL 실행은 됩니다.  로드만 실패합니다.
  2. Visual Studio MFC가 설치되어 있지 않은 프로그램에서 확장 DLL을 로드하는 프로그램을 실행하면 MFC DLL이 없다고 에러납니다. (mfc1004.dll이였나.. 기억이 가물하네요). 이경우에는 Visual C++ 재배포 패키지를 설치하거나 Visual Studio 설치 위치 뒤져서 dll을 찾아서 같은 실행 폴더에 놓아야 합니다.

정적 DLL은 그럴 필요 없습니다. 정확한 차이와 개념은 검색해서 공부하시길 추천합니다.