이번에는 DLL 파일을 클라이언트로 파싱하는 것을 해보려고한다.

 

DLL 프로젝트를 만들기전에 기본적인 프로젝트 세팅을 먼저해준다.

 

1. 빈 프로젝트 만들기

처음에 빈프로젝트를 만들어주고 다음과 같이 솔루션만 남겨놓고 만들어진 프로젝트를 지워준다.

 

2. Client 프로젝트와 DLL 프로젝트 만들기

비어있는 솔루션에 오른쪽 마우스 클릭 후 Client 프로젝트와 DLL 프로젝트를 만들어준다.

Client 프로젝트는 콘솔 응용 프로그램

DLL 프로젝트는 DLL(동적 라이브러리) 프로그램으로 만들어준다.

 

 

3. DLL 프로젝트에 매니지먼트 클래스 만들기

매니지먼트 클래스는 클라이언트 프로젝트에 DLL의 정보를 넘겨주기 위한 클래스이다.

매니지먼트 클래스는 한 개만 사용할 것이므로 싱글톤 클래스로 만들어준다.

 

.h

#pragma once
class CManagement
{
private:
	CManagement();
	~CManagement() = default;

public:
	static CManagement* Get_Instance();

	static void Destroy_Instance();

	void TestFunc();

private:
	static CManagement* m_pInstance;
};

 

.cpp

매니지먼트 객체는 static 형식이기 때문에 초기화는 다음과 같이 진행한다.

#include "Management.h"
#include <iostream>

using namespace std;

CManagement* CManagement::m_pInstance = nullptr;

CManagement::CManagement()
{
}

CManagement * CManagement::Get_Instance()
{
	if (m_pInstance == nullptr)
	{
		m_pInstance = new CManagement;
	}

	return m_pInstance;
}

void CManagement::Destroy_Instance()
{
	if (m_pInstance != nullptr)
	{
		delete m_pInstance;
		m_pInstance = nullptr;
	}
}

여기서 주의해야 할 점은 DLL 파일은 클래스의 선언부(.h)를 넘겨주는 것이기 때문에

정의부(.cpp)는 위와 같이 넘겨주는 클래스에서 정의해줘야 한다. 

 

4. DLL 안에 있는 정보를 내보내기 전 세팅 

DLL 파일을 파싱하기 위해서는 _declspec 키워드를 넘겨주고 싶은 클래스의 헤더파일에 클래스명 앞에 명시해준다.

 

 

_declspec 키워드에는 dllexport와 dllimport가 있다.

dllexport : DLL에서 데이터, 함수, 클래스 또는 클래스 멤버함수를 내보낼 수 있다.

dllimport : .def 파일을 사용할 필요가 없도록 내보내기 지시문을 개체 파일에 추가한다.

 

5. 매니지먼트에 테스트용 함수 만들기

#include "Management.h"
#include <iostream>
using namespace std;

CManagement* CManagement::m_pInstance = nullptr;

CManagement::CManagement()
{
}


CManagement::~CManagement()
{
}

void CManagement::TestFunc()
{
	cout << "DLL Test!!" << endl;
}

6. DLL 파일 생성

매니지먼트에 테스트용 함수까지 만들었으면 해당 DLL 프로젝트에서 솔루션 빌드를해준다.

솔루션 빌드를 했을 때 다음과 같은 오류가 나올 수도 있다.

 

이 오류는 프로젝트 구성형식이 dll 파일이 아닌 다른 파일로 지정되어있을 때 발생한다.

해당 오류가 발생 시 다음과 같이 프로젝트 속성 -> 일반 -> 프로젝트 구성 형식을 바꿔준다.

 

 

그리고 출력 디렉터리를 수정하여 DLL 파일이 제대로 뽑혔는지 확인한다.

경로 수정은 자유이다.

 

7. 클라이언트로 파싱

클라이언트로 파싱을 해주기 위해서는 먼저 클라이언트 프로젝트 속성에서

추가 종속성에 라이브러리 파일을 추가해줘야한다.

라이브러리 파일은 TestDLL 프로젝트를 빌드하면 .dll 파일과 함께 같은 폴더(실행 파일 폴더)에 생성된다.

 

 

여기까지 완료하였으면 DLL 프로젝트 폴더에 있는 매니지먼트 헤더 파일을 복사하여 클라이언트 폴더로 붙여준다.

 

이유는 다음과 같이 헤더 파일을 Include 해주려고 할 때 상대경로까지 적어줘야될 필요없이 작업을 하기 위해서이다.

#include "../TestDLL/Management.h" // 파일 복붙을 안했을 때

#include "Management.h"            // 파일 복붙을 했을 때

 

헤더 파일을 복사하고나서 TestDLL 프로젝트의 DLL 파일이 있는 경로로가서 dll파일과 lib파일을 복사하여

dll 파일은 클라이언트 실행 파일이 있는 폴더로,

lib 파일은 클라이언트 솔루션 파일이 있는 폴더로 붙여넣기를 해준다.

 

여기서 lib 파일은 어느 폴더에 있던 상관없다.

다만 추가 포함 디렉터리에 해당 파일이 있는 폴더의 경로를 추가 해줘야 한다.

 

 

각 폴더에 파일을 옮기고나서 다음과 같이 정의하여 클라이언트에서 빌드를 하게되면,

dll 프로젝트에 만들었던 함수가 실행되는 것을 볼 수 있다.

 

#include "stdafx.h"
#include "Management.h"     

int main()
{
	CManagement* m_pManagement = CManagement::Get_Instance();

	m_pManagement->TestFunc();

    return 0;
}

 

'Programming > DLL' 카테고리의 다른 글

정적라이브러리와 동적라이브러리의 장단점  (0) 2021.01.25

정적라이브러리 .lib : 빌드과정도중 링크단계에서(런타임 이전) 실행파일과 연결이된다.

동적라이브러리 .dll : 프로그램 실행도중(런타임 이후) 참조

 

정적라이브러리

-장점-

- 런타임 과정에서 변경되는 부분이 없기 때문에 빠른 실행 속도를 보장

 

-단점-

- 매번 재빌드를 해야하기 때문에 메모리를 더 차지하게된다.

- 컨텍스트 스위칭이 빈번하여 메인 메모리를 더 사용하게된다.

 

동적라이브러리

-장점-

- 컨텍스트 스위칭이 정적라이브러리에 비해 비교적 적게 일어나기 때문에 메모리 비중이 적다.

 

-단점-

- 외부 의존도가 발생하기 때문에 이식성이 어렵다.

- 성능저하로 인해 속도가 느려질수있다.

- 동적 라이브러리는 정적 라이브러리에 비해 사용이 복잡하기 때문에

  공유 라이브러리를 메모리에 올리려면 해당 라이브러리를 찾고 올리는데까지 시간이 걸린다.

'Programming > DLL' 카테고리의 다른 글

DLL 파일 내보내기  (0) 2021.01.27

+ Recent posts