C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[1017] C++Builder XE dll 동적 폼 호출 정리.
워프 [seunghoe9] 11933 읽음    2010-11-12 22:45
안녕하세요. 워프입니다.
C빌더 입문한지 일주일이 안되었지만
이번에 dll 동적 폼 호출 부분때문에 많은고생하여
정리 하고, 혹시나 저와같으신 분들이 계실까...
고생을 좀 덜어 드릴까.. 하는 마음에 글을 씁니다.

소스를 첨부하여 드리며 현재 C++ Builder XE에서 작업하였으나
2010, 2009 버전까지는 확인해 보았습니다.

과정은 아래와 같습니다.

1. dll 생성을 위해 메뉴에서 File -> New -> Other를 선택하여 C++builder Project의
   Dynamic-link Library(dll) 를 선택합니다.

2. source type 은 c++ 체크, use vcl 체크 합니다.

3. 아래와 같은 코드가 보이고 이곳에 해당 인터페이스를 만들어 주게 됩니다.

#include <vcl.h>
#include <windows.h>

#pragma hdrstop
/****어쩌구저쩌구*****
*********************/

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
    return 1;
}

4. 우선 열려있는 파일의 이름을 임의대로 변경, 저장합니다. 저는 dll_form.cpp로 변경, 저장하였습니다.

5. dll_form로 프로젝트명도 변경, 저장하였습니다. 변경후에는 dll_form.dll 이라는 프로젝트로 됩니다.

6. * 이제 폼을 먼저 추가합니다.

7. 프로젝트 메니져에서 현재 dll프로젝트에 Add New -> Form 을 선택합니다.

8. Unit1.cpp 이 보이시고.. 이제 이곳에(dfm) 버튼 부터.. 등등 화면을 디자인하고 코딩합니다.

9. 폼을 저장하세요. (저는 dllform.cpp로 저장하였습니다.)

10. 이제 이 폼을 동적으로 사용하기위해 아래와 같이 작업합니다.

11. WINAPI DllEntryPoint함수가 들어있는 파일을 여시고 코딩합니다.


//------------------------ dll_form.cpp --------------------------------------

#include <vcl.h>
#include <windows.h>
#include "dllform.h"    // 추가하는 폼의 헤더를 include합니다. dllform.cpp(폼)을 여시면
                        // dllform.cpp, dllform.h, dllform.dfm 이 보이시는데 이중 h(헤더)
                        // 파일을 include 하는 겁니다.

USEFORM("dllform.cpp", dllFrm); // 추가된 폼의 cpp파일 내용의
                //    extern PACKAGE TdllFrm *dllFrm;
                //    이부분에서 소스처럼 dllFrm 이라적으면
                //
                //   TdllFrm* dllFrm => 처럼 하지 않아도 됩니다.
                // 
                //   명시한 dllFrm 포인터를 바로 사용할수 있습니다.


#pragma hdrstop
//---------------------------------------------------------------------------
//   Important note about DLL memory management when your DLL uses the
//   static version of the RunTime Library:
//
//   If your DLL exports any functions that pass String objects (or structs/
//   classes containing nested Strings) as parameter or function results,
//   you will need to add the library MEMMGR.LIB to both the DLL project and
//   any other projects that use the DLL.  You will also need to use MEMMGR.LIB
//   if any other projects which use the DLL will be performing new or delete
//   operations on any non-TObject-derived classes which are exported from the
//   DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
//   EXE's to use the BORLNDMM.DLL as their memory manager.  In these cases,
//   the file BORLNDMM.DLL should be deployed along with your DLL.
//
//   To avoid using BORLNDMM.DLL, pass string information using "char *" or
//   ShortString parameters.
//
//   If your DLL uses the dynamic version of the RTL, you do not need to
//   explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------

#pragma argsused

// 아래는 동적으로 폼을 보이기만 합니다. 호출하는 곳에서는 호출된 폼만 보입니다.
extern "C" __declspec(dllexport) void __stdcall showForm(void)
{
    dllFrm = new TdllFrm(0);
    dllFrm->ShowModal();

    delete dllFrm;

}

// 아래는 동적으로 생성된 폼의 객체를 포인터로 넘기는 부분입니다.
// 이처럼 포인터로 넘겨 호출한곳에서 객체(폼)를 사용합니다.
extern "C" __declspec(dllexport) TForm* __stdcall getFrm(void)
{
    dllFrm = new TdllFrm(0);
    return dllFrm;
}

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
    return 1;
}
//---------------------------------------------------------------------------


12. 저장하시고 빌드합니다.

13. 이제 이 DLL 파일을 호출하는 프로그램을 만들기위해 메뉴에서 Project를 선택하시고
    Add New Project 선택합니다.

14. VCL Form Application을 선택하여 프로젝트를 추가합니다.

15. 폼이 하나 생성되며 여기에 버튼 컨트롤 2개를 놓습니다.

16. 각각의 버튼은 "동적 폼 객체가지고 오기" 버튼과 "동적 폼 보이기" 라고 명시하였습니다.

17. 이제 아래와 같이 버튼 이벤트에 각각 코드를 입힙니다.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    HINSTANCE hdll;          // hdll 인스턴스타입 변수 생성

    hdll = LoadLibrary(L"dll_form.dll");  // 만들어 놓은 dll의 위치를 포함하시면됩니다.
                                               // 전 같은위치에 놓았습니다.

    typedef __declspec(dllimport) TForm* (*GETFRM)(void);   // 호출할 함수포인터 타입지정

    GETFRM getform = (GETFRM)GetProcAddress(hdll,"getFrm"); // dll의 getFrm함수를 가지고
                                                                 // 옵니다.


    TForm* usefrm = getform();    // 가지고온 함수를 호출하고 리턴값에 맞게(TForm*) 포인터
                                       // 에 가지고온 함수를 넣습니다.(주소값)

    usefrm->ShowModal();         // 이제 usefrm은 dll의 dllfrm과 같은 객체입니다. 마음껏
                                      // 요리합니다.

}

void __fastcall TForm1::Button2Click(TObject *Sender)
{
    HINSTANCE hdll;
    hdll = LoadLibrary(L"dll_form.dll");

    typedef __declspec(dllimport) void (*SHOWFORM)(void);

    SHOWFORM showform = (SHOWFORM)GetProcAddress(hdll,"showForm");

    showform();  // 위와 같습니다. 다만.. 폼 인스턴스를 리턴하지는 않는 ... 함수입니다.

}

/* 이처럼 각각의 dll을 만들고 그 화면에 업무로직(총무부,인사부,...)을 작성하여 dll나누고
   프로그램은 exe를 메인으로두고 업무가 바뀌어 화면을 수정해야 하는경우 그 업무화면의 dll만
   새로 배포 하시면 되는... 용도에 쓰면 좋켔네요 ㅎㅎ;
   메뉴도 동적으로 만들어서 각 업무부서의 이름.dll 을 호출하는 형태..
   추후에 네트워크를 통한 프로그램 업데이트 하는 부분과 동적메뉴생성하여 적용하는 부분까지
   만들어 봐야겠습니다. 그때 다시 팁에 올리도록하겠습니다. */


// 여기까지입니다.... 설명이 좀;;; 부실합니다. 초급분들이 쉽게 이해하시도록 한건데..
// ㅠㅠ 소스 첨부합니다.  첨부한 소스는 반드시 전체 빌드 해주세요...

+ -

관련 글 리스트
1017 C++Builder XE dll 동적 폼 호출 정리. 워프 11933 2010/11/12
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.