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

C++빌더 Q&A
C++Builder Programming Q&A
[16948] Re:Re:C++Builder 에서 DLL을 만들어서 VC++에서 사용하기?(제발 꼭 가르쳐주세요...)
이성욱 [] 1302 읽음    2002-03-28 05:46
만해 님이 쓰신 글 :
: 이성욱 님이 쓰신 글 :
: : CBuilder에성 DB관련 DLL을 만들어서 관련 Record들을 Structure의 각 해당요소에 저장하고
: : 이에대한 최종결과로 이 structure를 보내려는 함수를 만들려고 합니다.
: : 물론, 이 함수는 VC++에서 사용이 되구요...
: : 지가...처음 C++Builder를 접하다 보니...내공이 좀 모자라군요....
: : 지나가는 고수님들 ... 도움을 간절히 바랍니다...
: :
: : 지금 제가 하려고 하는 것은 VC++에서는 AFX_EXT_CLASS와 같은 역할을 하는 것임돠...
: :
: : 제발...아시는 분들 꼭 가르쳐 주세요...
: :
: : 예)
: : typedef struct tagTEST
: : {
: :    int     nNumber;
: :    char *  strRecordName;
: :    ...
: : }TEST,*PTEST;
: :
: : extern "C" __declspec(dllexport) TEST* TestFunc();
: : ....
: : ....
: : TEST* TestFunc()
: : {
: :    PTEST ttt = new TEST;
: :    ttt->nNumber = 1;
: :    ttt->strRecordName = "TEST";
: :    return ttt;
: : }
: :
: : ..
: : 위의 함수와 같이 TestFunc가 내가 만든 스트럭쳐형의 포인터를 리턴하도록 하고 싶은데...
: : 막상 구현을 할려구 하니 않되던군요...
: : 꼭 쫌부탁드립니다...고수님들...
: :
: :
:
: 안녕하세요 만해입니다.
:
: Visual C++ 에서 만든 DLL을 빌더에서 사용하는 방법은
:
: http://www.bcbdev.com/articles/vcdll.htm
:
: 여기를 참고 하시면 됩니다.
:
: 그럼 이만~
:
제가 질문한 것은 VC++에서 만든 DLL을 C++Builder에서 사용하는 것이 아니라 그 반대 사항에 대해
서 질문을 한 것인데,,..쩝...어째든 답변 주세서 감사하구요...오늘 듸뎌 해결했습돠....흐뭇...
혹시 저 같은 사람이 똑 있을 것 같아서...좀 미흡한면은 있지만...설명을 올리려 합니다.

먼저, 제가 구현하려구 한것은 빌더에서 DLL을 만들도록 한 것입니다.
이 DLL에서는 VCL Form 및 기타 다른 Component(특히 DB에 관련 된것, VC++는 DB 다루는 것이 완존히 생 노가다거든요...^^)를 포함하게 됩니다. 이렇게 빌더 DLL에서 DB에 관련된 사항을 모두 다루도록 한 후 나중에 VC++에서 사용하게될 Field들을 Structure로 구현해서 DB 해당 Field를 스트럭쳐의 Field로 맵핑을 해서 빌더 dll에 속해있는 export할 함수에서 리턴하도록 한것입니다.
구지 이렇게 구현한것은 앞에서도 언급한 바와같이 VC++가 DB를 다루기위해서는 노동력을 많이 투자해야 되거든요...그래서 RAD 툴인 빌더에서 이에 관련된 사항들을 편하게 다루고 최종적으로 이에 관련된 정보를 스트럭쳐를 통해 보내는 거지요...

  이제 구현하려구하는 목적을 설명했으니...실제...코딩에 대해서 설명하게 슴돠...

1. 빌더에서..Dll wizard를 사용해서...Dll project를 생성한 후 원하는 Form을 구성합니다.
   이에 대해서는 지면관게로 참고서적(참고 할게 별루 없지만?)을 봐 주시구요...
   이렇게 해서 Form design을 마쳤으면,,,실제,,,export시킬 스트럭쳐와 함수를 선언하도록 합니
   다. 구체적 코드는 아래와 같습니다.
  
   1) 스트럭쳐 선언..
     typedef struct tagSmallStructure
     {
          int     nVersion;
          char   *strStructureName;   // 문자열의 경우는 Builder와 VC++간의 문제의 소지를
                                    // 미연에 막고, 신경을 들쓰기위해 Character의 포인터로
                                      //사용함.
     }*PSMALLSTRUCTURE,SMALLSTRUCTURE;

     typedef struct tagTEST
     {
         int              nVersion;
         char             *strName;
         SMALLSTRUCTURE   MySmallStructure;
     }*PTEST,TEST;

    2) Export시킬 함수의 선언 및 구현

      2)-1. 함수의 선언(해당 Unit파일의 헤더에 선언)
            extern "C" __declspec(exportdll) PTEST MyTestFunc();

      2)-2. 함수의 구현(해당 Unit파일의 구현부)
            PTEST MyTestFunc()
            {
                 PTEST pTestStruct = new TEST;
                
                 pTestStruct->nVersion                          = 2;
                 pTestStruct->strName                           = "This is test structure1";
                 pTestStruct->MySmallStructure.nVersion         = 1;
                 pTestStruct->MySmallStructure.strStructureName = "This is test structure2;
                
                 return pTestStruct;
            }
    여기까지가 빌더에서 해주는 일입니다. 참 저의 경우는 Form내에서 ADOTable,ADOConnection,..
등 DB에 관련된 Component들을 쓰다보니, 나중에 VC++에서 호출을 할때, ...CoInitialize...어쩌구하는 Error이 발생하더라구요...그래서...VC++코드에서..빌더의 DLL함수를 호출하기 전에 CoInitialize(NULL) 및 호출 후 CoUnInitialize()라는 함수를 불러서 Error를 해결했습니다. 이에대한 자세한 사항은 Q&A에서 자료를 찾아 볼 수가 있어구요...더 자세한 설명을 원하시는 분은 그 부분을 검색하셔서 보심되겠구요..(검색어:CoInitialize)

2. 간단하게 Test를 하기위해서 MFC Dialog based form을 만드시구요...그 위에 버튼을 하나 언저 
  서 ButtonClick event handler를 생성시킨 후 아래와 같이 코딩을 합니다. 참 깜빡했군요..event
  handler를 작성하기에 앞서서 구현부(물론 아무곳이나 됨)에 위 1의 1)에서 한것과 같이 structu
  re들을 선언하세옆....^^;
  
   1) ButtonClick event handler 내부에...
     아래코드는 제가 테스용으로 만든 프로그램의 실제 구현부 소스입니다. 참고하세요..

     void CCBuilderDllTesterDlg::OnButton1()
     {
    // TODO: Add your control notification handler code here
    HINSTANCE        hInst;
    PTEST            (*pFunc)();
    PTEST            ttt;
    HRESULT            hResult;

    if((hInst=LoadLibrary("CraneSimMainProj.dll"))==NULL)
    {
        AfxMessageBox("파일을 찾을 수 없습니다");
        return ;
    }

    hResult = CoInitialize(NULL);  <-- 이 부분이 아까 설명한 그 "...CoInitialize.."Error
    if(FAILED(hResult))
    {
        AfxMessageBox("ADODB Initialize Error!");
        return ;
    }
    pFunc=(PTEST (*)())GetProcAddress(hInst,"_TestFunc");

    ttt = (*pFunc)();
   
    if(ttt->nVersion == 2)
    {
        AfxMessageBox(ttt->pStrTest);
        if(ttt->SmallTest.nVersion == 2)
        {
            AfxMessageBox(ttt->SmallTest.pSmallTest);
        }
    }
    CoUninitialize( );
   
       }

       저는 빌더 Dll을 명시적인 방법으로 함수를 호출했는데요...암시적인 방법으로는 잘 않되더라구요...처음 이 것을 테스트 할때는 너무나도 모르는 것이 많아서..그냥 맘 편하게 명시적인 방법으로 구현했슴돠..나중에 암시적인 방법으로도 구현 해보구...기회가 있슴...다시 올리도록 하줘..
근데...이 명시적인 방법으로 구현할때 주의를 요하는 것은 호출한 함수명을 주의깊에 살펴봐야 한다는 것입다..무슨 이유인진 잘 모르겠지만...빌더 dll을 생성하고나면,,,처음 export실킬때의 이름앞에 "_"가 붙어져 있더군요...저는 이놈 때문에 몇시간씩 해맸습니다. 이러한 것에 대한 확인은 dll과 함께 만들어 지는 lib파일을 메모장이나 다른 편집기를 열어서 맨아랫줄에서 확인을 해보면..
처음 export시킬때의 이름인지...아님...이름앞에 뭐가 붙어 있는 지를 확인 하실 수 있슴돠..
지금까지의 설명이 너무 장황했던것 같은데....사실...이거 해결하려구...이틀동안 뺑이를 쳤거든요... 그래서 저같은 사람이 다신 나오지 말라는 뜻에서 임돠...
그럼 즐프하시구요....
그동안 여기서 도움만 받았는데...그나만...도움을 줄 수 있어서...즐겁습니다..




    

+ -

관련 글 리스트
16845 C++Builder 에서 DLL을 만들어서 VC++에서 사용하기?(제발 꼭 가르쳐주세요...) 이성욱 882 2002/03/26
16862     Re:C++Builder 에서 DLL을 만들어서 VC++에서 사용하기?(제발 꼭 가르쳐주세요...) 만해 1104 2002/03/27
16948         Re:Re:C++Builder 에서 DLL을 만들어서 VC++에서 사용하기?(제발 꼭 가르쳐주세요...) 이성욱 1302 2002/03/28
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.