본문 바로가기

MFC

[MFC] 정적 DLL 만들기(스크랩)

출처 : http://blog.daum.net/cjp777/4


DLL 만들기 라고 검색해 보았는가?

당연히 검색 해봤으니 이 글도  읽게 되겠지?? ㅋㅋㅋㅋㅋㅋ

오만가지 방법이 다나온다

명시적으로 내보내기, def로 내보내기, ......암튼 널려있다

해보니 전부 잘되던가?

아니 안되는게 태반이다

블로그에 올라온 글들이 사실 많은걸 감추고 있기 땜시

다 까발리면 밥줄 끊길까봐? ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

진담이다.

난 하수라 밥줄 끊길일 없으니

자세히 써주시것다.

일단 비쥬얼 스튜디오 2010 기준이고 다른버전은 테스트 안해봤다.

그러니 하수인

 

것이다.

친절하게 스샷 노가다로 설명 하시것다.

1. 프로젝트 생성

 

MFC DLL을 선택하고 이름은 알아서 확인

아 여기서 되도록 솔루션용 디렉터리 만들기에 체크한다 DLL 사용하기 프로젝트도 같이 만들기위해

한개폴더에 같이 넣기 위해서다

 

확인하믄 다음 페이지가 나오는데 별거없으니 패스하고 그다음 패이지가 있다

 

여기서 두번째를 선택한다.

그래야 정적 DLL을 만들수 있다.

선택하고 마침 클릭

 

요렇게 파일들이 생성 됐으면 일단 잘된거다.

그리고 이래저래 설명이 힘들어 질수있으니

유니코드는 사용하지 않겠다.

DLL 프로젝트 속성에서 구성속성->일반->문자집합 요기에서

멀티바이트 문자집합 사용으로 바꾸면 된다.

 

뭐 어차피 하는거 지대로 설명 하시것다.

1. 함수별로 반환값이나 인자를 골고루 줘보자

2. DLL로 다이얼로그 까정 띄우자

3. 2번땜시 외부로 내보내는 함수를 여러개 만들자

사실 여기가 핵심이지 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

 

먼저 DLL로 다이얼로그 띄우기를 하기전에

DLL이 잘동작하는지 테스트해볼 프로 젝트가 하나 있었으면 좋겠네

만들자!!!!!!!!!!!!!!!!!!!!!! 스샷 설명은 사실 좀 후회가 된다ㅡㅡ; ㅡㅡ;

 

암튼 솔루션에서 마우스 오른쪽 눌러서 새프로젝트 만들기 한다

 

MFC 응용 프로그램선택하고 이름정하고 확인

 

대화상자 기반으로 만들고

DLL도 멀티 바이트로 만들었으니

테스트용 응용프로그램도 유니코드 체크는 빼자

뭐 고수라면 잘 컨버팅 하가면서 해도 문제는 없겠다.

여기서 다음다음다음 마침 하믄 끝이다.

 

이런식으로 프로젝트 2개가 생성되었다

DLL 생성용 그리고 DLL 테스트용

 

이제 DLL에 함수 하나를 만들어보자

 

DLLMake.cpp 를 열고

BOOL CDLLMakeApp::InitInstance()

요런 함수 보일것이다

 

그럼 그아래에 코딩해보자

void WINAPI GetTestMsg(char* pMsg)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
  
 CString strTset;
 strTset.Format("%s", pMsg);
 AfxMessageBox(strTset);
}

아주 쉬운 코드로 이렇게 그냥 메세지 박스를 출력하는 함수다

그다음 DLLMake.def파일을 열어서 작업한다

 

이렇게 적는다

LIBRARY "DLLMake" 이거는 출력 DLL 파일에 이름이다.

 

EXPORTS는 내보내기란 뜻인데

GetTestMsg   @1

첫번째 내보내는 함수는 이거란 뜻이다 함수 이름만 적으면 된다 인자나 반환값은 표기하지 않는다.

 

그럼 이게 잘되나 테스트 해보자

그러기위해 속성값한번더 수정하자 스샷 한거 진짜 후회된다 ㅡㅡ;

 

속성 선택

 

빌드이벤트->빌드후 이벤트선택후

명령줄->편집

 

매크로 버튼을 누르면 이렇게 나오는데

중요한건 copy 명령어다 하다보면 알겠지만 lib 파일을 복사해야 디버깅이고 뭐고 할수있으므로

매번 dll수정되면 복사하는 번거로움을 줄이기위해 이 명령어를 넣는다 나름 상당히 유용하다

copy "$(OutDir)\DLLMake.lib" "$(SolutionDir)\DLLTest"

설명하자면 DLL 파일과 lib 파일이 출력되는 디렉토리에서 DLLMake.lib를 DLLTest프로젝트가 있는 폴더로 복사하는 것이다

뭐 그냥 copy "d:\_Project\_svn\DLLMake\debug\DLLMake.lib" "d:\_Project\_svn\DLLMake\DLLTest\" 이렇식으로 매크로 사용 안하고 풀패스로 작성해도 무관하다 그건 편한데로 하시길

이제 테스트 하자 

 

시작 프로젝트는 항상 DLLTest로 해놓자

뭐 잘 알겠지만 DLL 자체만으로는 아무것도 할수없으니...

이렇게 하면 DLLTest 글자색이 진해졌을것이다

그럼 DLL로 만든 함수를 호출해보자

 

DLLTest에 stdafx.h 파일을 열자

 

 

__declspec( dllimport ) void WINAPI GetTestMsg(char* pMsg);
#pragma comment(lib, "DLLMake")

 

*******(dllimport!)<---- !표는전부 빼야함 바로위에 스샷 처럼 해야 에러안남

****** 편집 페이지에서는 보이지않는게 등록하면 보이는군 이거 이상하네 *******

 

이렇게 입력하자

그리고 빌드 해보자

여기서 DLLMake.lib 라이브러리 파일을 찾을수 없다고 나오면

위해서 얘기한 copy 부분을 다시 해보기 바란다

아무리해도 cpoy가않된다고 판단되면

DLLMake.lib 파일을 찾아서 DLLTest.vcxproj 가있는 곳으로 그냥 복사하자

이렇게 하면 DLLMake를 수정할때마다 복사해야한다

한마디로 개 노가다라 할수있것다.

 

stdafx.h에 선언까지 했다면 실제 써보자 잘되는지

 

버튼 캡션에 호출할 함수명을 써주는 친절함이란   훗..................

이벤트 처리기 추가하고

추가된 함수에

void CDLLTestDlg::OnBnClickedButton1()
{
 ::GetTestMsg("Test Msg");
}

 

위와 같이 입력해보고 실행 해보시라

 

이렇게 뜬다면 잘 따라했고 내가 빡시게 스샷찍은 보람도 있겠다 ㅋㅋㅋㅋㅋ

여기까지 하믄 앞으로는 정말 쉽다.

 

다시 DLLMake 프로젝트로 돌아가서

DLLMake.cpp 파일 아까 GetTestMsg 함수가 있는데로가서

하나더 추가해보자 그냥 복습차원에서 추가해보자

char* WINAPI InputIntOutputCString(int nIndex)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());

 char szData[100];
 ZeroMemory(szData, sizeof(szData));
 sprintf_s(szData, 100, "%d이 들어옴", nIndex);

 return szData;
}

이렇게 넣고 *경고가 나오는데 무시하자 일단은*

DLLMake.def에

 

InputIntOutputCString @2

마찬 가지로 반환값이나 인자는 제외하고 함수명만 적어준다

 

DLLTest 프로젝트로 돌아가서

stdafx.h에

__declspec(dllimport) char* WINAPI InputIntOutputCString(int nIndex);

추가한다

 

 

이런식으로

아무리 생각해도 과도한 스샷 질이라 생각한다 ㅡㅡ;

이번에는 스샷없이 넘어가자 버튼도 아까 처럼 하나더 만들고

void CDLLTestDlg::OnBnClickedButton2()
{
 CString strValue;
 int nIndex = 50;
 char szData[100];
 ZeroMemory(szData, sizeof(szData));
 strcpy_s(szData,100, ::InputIntOutputCString(nIndex));

 strValue.Format("%s", szData);
 AfxMessageBox(strValue);
}
테스트 해보자 잘되면 성공이다 

이런식으로 되면 성공이다 ㅋㅋㅋㅋㅋ

여기서 잠깐 참고로 얘기하자면 DLL에서 사용 되는 함수들은 되도록 C/C++에서 사용되는 자료형으로 반환값이나 인자를 정하는게 일단 편하다 반환값을 CString 등으로 하믄 링크 에러가 발생한다 LNK1120에러인데 이거 해결하기 아주 힘들고 복잡하다

이부분은 알아서 하시고 일단 MFC용 자료형 같은건 되도록 금하자

다음은 DLL에서 다이얼로그 하나 띄워보자

 

DLLMake에서 클레스 추가 MFC 클래스로 추가한다

 기본 클래스를 CDialogEx로 하고

class명을 DLLMakeDlg라 하고 마침 한다..

 

리소스에 다이얼로그를 편집하고

스샷은 패스

계속 편집하던 DLLMake.cpp에 추가한다

먼저 #include "DLLMakeDlg.h" 해주시고

void WINAPI PopUpDialog()
{
 DLLMakeDlg dlg;
 dlg.DoModal();
}

맨아래에 이렇게 추가해주자 진짜 별거없다

 

계속 편집하던 DLLMake.def에도 추가해준다

그래고 빌드

 

다시 DLLTest로 돌아가서 다이얼로그를 편집하자

맨아래 추가된것처럼 버튼 하나더 만들고

 

void CDLLTestDlg::OnBnClickedButton3()
{
 ::PopUpDialog();
}

이런식으로 코딩하자

stdafx.h에 당연히 선언해주야겠지

__declspec(dllimport) void WINAPI GetTestMsg(char* pMsg);
__declspec(dllexport) char* WINAPI InputIntOutputCString( int nIndex);
__declspec(dllimport) void WINAPI PopUpDialog();
#pragma comment(lib, "DLLMake")

기존꺼랑 전부 합쳐서 이정도?

 

그럼 그냥 실행 고고

 

위와같이 뜰것이다 왼쪽은 DLLTestDlg에서 만드 버튼이고

오른쪽이 DLLMake에서 만든 다이얼로그다

 

스샷을 이용해 어렵게 설명했지만

막상 할려고 하면 잘안되고

이해 안되는 부분이 많을 것이다

이글을 쓰고있는 이시접에 나도 잘 모르는 부분이 상당히 많이 있다

아무튼 나름 쉽고 세심하게 설명하기위해 노력했으므로

나름 만족한다

 

잘못된부분이 있다면 과감히 얘기해 주기 바란다

난 아직 하수니까 ㅡㅡ;

퍼갈때는 출처를....


'MFC' 카테고리의 다른 글

[MFC] DLL 만들기 Sample Code  (0) 2014.02.04
[MFC] 확장 DLL 만들기(스크랩)  (0) 2014.02.04
[MFC] CSocket(비동기) Error정리  (0) 2014.01.22
[MFC] CSocket Timeout 구현하기  (0) 2014.01.22
[MFC] HRESULT 반환값  (0) 2014.01.16