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
[57562] Re:Re:Re:Re:동적 연결 Package 에 함수 export 하여 사용하는 방법
장성호 [nasilso] 989 읽음    2009-07-10 20:14
죄송합니다.
제가 잘못 답변드렸네요

PACKAGE를 사용해서는 C 스타일로 함수이름 그대로 extern되지 않네요

CBuilder 네임멩글링 규칙에 따라 extern되네요.
PACKAGE 키워드는 동적으로 LoadLibrary + GetProcAddress 로 쓰기엔 맞지 않는것 같습니다.

참고로  CBuilder 네임멩글링 규칙을 보니 ..

1) global변수인경우
     변수이름 앞에 언더바('_') 가 붙어서 extern되구요
    
     PACKAGE int  iAbc;
     "_iAbc" 로 extern됩니다.

2) 함수인경우 이름앞에 꼴뱅이('@')가 붙고 뒤에는 파라메타에 따라 뒤에 다르게 붙습니다.

    int MyFunc();                        는      "@MyFunc$qv"
    int MyFunc(String s);            는      "@MyFunc$qqr17System@AnsiString"

3) class의 멤버함수인 경우
    int  myclass::MyFunc(String s)  는   "@myclass@MyFunc$qqr17System@AnsiString"
   

  정확하진 않지만 대충 위와같은 식으로 extern됩니다.

편법이지만
만약 2번 또는 3번과 같이 extern된 경우 앞에 메임멩글링 규칙을 잘 모르니
앞부분의 string만으로 GetProcAddrss 할수도 있습니다.

다음 팁을 쓰면요..
http://www.delmadang.com/community/bbs_view.asp?bbsNo=3&bbsCat=0&st=C&keyword=MyGetProcAddress&indx=402177&keyword1=MyGetProcAddress&keyword2=&page=1

function MyGetProcAddress(hModule : LongWord; pszSymbol : PChar) : Pointer;
type
    TWordArr = array [0..0] of Word;
    PWordArr = ^TWordArr;
    TLongWordArr = array [0..0] of LongWord;
    PLongWordArr = ^TLongWordArr;

var
    // 각 파일 구조체 선언
    pImageBase : PUCHAR;
    pImageDosHeader : PIMAGE_DOS_HEADER;                       // IMAGE_DOS_HEADER
    pImageNtHeaders : PIMAGE_NT_HEADERS;                        // IMAGE_NT_HEADERS
    pImageDataDirectory : PIMAGE_DATA_DIRECTORY;             // IMAGE_DATA_DIRECTORY
    pImageExportDirectory : PIMAGE_EXPORT_DIRECTORY;       // IMAGE_EXPORT_DIRECTORY

    dwFuncIndex : LongWord;
    pFuncName : PChar;

    FnIndex: LongWord;

begin
    Result := nil;

    pImageBase := PUCHAR(hModule);

    // 매핑되지 않았다면 종료
    // 매핑되지 않았다는 것은 DLL의 주소가 잘못되었다는 것.
    if not Assigned(pImageBase) then Exit;


    pImageDosHeader := PIMAGE_DOS_HEADER(pImageBase);

    // PE 포멧 파일인지 확인하여 PE파일이 아니라면 종료한다.
    // PE (Portable Executable) 포멧 파일은 Exe, Dll에 해당한다.
    // PE 구조는 IMAGE_DOS_HEADER, IMAGE_FILE_HEADERM, IMAGE_OPTIONAL_HEADER32 헤더로 구성된다.
    // IMAGE_DOS_SIGNATURE  0x5A4D (23117 : MZ)
    if pImageDosHeader.e_magic <> IMAGE_DOS_SIGNATURE then Exit;

    // e_lfanew : PE 헤더의 시작점을 가리키는 RVA 값이다.
    // 파일이 매핑된 주소의 시점부터 e_lfanew 값을 더하면 IMAGE_NT_HEADERS 가 나온다.
    pImageNtHeaders := PIMAGE_NT_HEADERS(LongInt(pImageBase) + pImageDosHeader.e_lfanew);

    // IMAGE_NT_SIGNATURE 를 확인한다.
    // IMAGE_NT_HEADERS의 시작지점이 $00004550 값인지 확인한다.
    // 0x00004550 (17744 : PE00)
    if pImageNtHeaders.Signature <> IMAGE_NT_SIGNATURE then Exit;

    pImageDataDirectory := @pImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];

    // IMAGE_EXPORT_DIRECTORY : export된 함수들을 담고 있는 구조체이다.
    pImageExportDirectory := PIMAGE_EXPORT_DIRECTORY(Cardinal(pImageBase) + pImageDataDirectory.VirtualAddress);

    dwFuncIndex := 0;

    // pImageExportDirectory.NumberOfFunctions : DLL 파일 내의 export된 함수의 갯수를 의미한다.
    // 처음부터 갯수만큼 돌면서 검색하려고 하는 함수가 존재하는 지 확인한다.
    while (dwFuncIndex < pImageExportDirectory.NumberOfFunctions - 1) do begin
        // 해당 주소의 함수명을 가져온다.
        pFuncName := PChar(PLongWordArr(Cardinal(pImageExportDirectory.AddressOfNames) +
                             Cardinal(pImageBase))^[dwFuncIndex] + Cardinal(pImageBase));

        // 검색하려고 하는 pszSymbol 함수와
        // DLL에서 검색된 pFuncName 함수를 비교한다.
        if StrLIComp(pszSymbol, pFuncName, Length(pszSymbol)) = 0 then begin
            // AddressOfNameOrdinals 순서수 테이블
            FnIndex := PWORDARR(Cardinal(pImageExportDirectory.AddressOfNameOrdinals) +
                            Cardinal(pImageBase))^[dwFuncIndex];

            // 검색하려는 함수명과 DLL에서 Export된 함수명이 같다면 해당 함수의 주소를 리턴한다.
            Result := Pointer(PLongWordArr(Cardinal(pImageExportDirectory.AddressOfFunctions) +
                          Cardinal(pImageBase))^[FnIndex] + Cardinal(pImageBase));
            Break;
        end;
        // 두 함수가 같지 않으면 Index를 증가해 다음 함수를 검색한다.
        inc(dwFuncIndex);
    end;
end;




#include "MyLib.hpp"
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    typedef void __fastcall ( *MsgFunc)(AnsiString str);
    if(OpenDialog1->Execute())
    {
        HINSTANCE hIns;
        hIns=LoadLibraryA(OpenDialog1->FileName.c_str());
        if(hIns)
        {
            //"@ImShowMessage$qqr17System@AnsiString"
            MsgFunc func;
            func=(MsgFunc)MyGetProcAddress((unsigned int)hIns,"@ImShowMessage$qqr17System@AnsiString");
            if(func)
            {
                func("메세지 잘 되나?");
            }
            FreeLibrary(hIns);
        }
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    typedef void __fastcall ( *MsgFunc)(AnsiString str);
    if(OpenDialog1->Execute())
    {
        HINSTANCE hIns;
        hIns=LoadLibraryA(OpenDialog1->FileName.c_str());
        if(hIns)
        {
            //"@ImShowMessage$qqr17System@AnsiString"
            MsgFunc func;
            func=(MsgFunc)MyGetProcAddress((unsigned int)hIns,"@ImShowMessage");
            if(func)
            {
                func("메세지 잘 되나?");
            }
            FreeLibrary(hIns);
        }
    }
}


주의할점은  비슷한 이름의 함수가 있다면 엉뚱한 놈을 return할수 있습니다.


그럼..


아루스 님이 쓰신 글 :
: PACKAGE 선언 시 동적 로드는 어떻게 해야하나요?
: 외부로 나타난 이름이 함수명 뒤에 () 표시가 들어가있는거 같은데 GetProcAddress 로 안나오네요.
:
:
:
: 장성호 님이 쓰신 글 :
: : 함수나 변수 선언할때
: : 앞에 PACKAGE 라고 쓰면 쉽게 EXPORT됩니다.
: :
: :
: : 아루스 님이 쓰신 글 :
: : : 그냥 일반 DLL 처럼하면 되네요.
: : : export 시에 함수 이름 앞에 underline 들어가는 걸 잊고 원래 함수 이름으로 찾아대니 못찾았던거네요. ㅜㅜ
: : :
: : : 아루스 님이 쓰신 글 :
: : : : 은 무엇일까요. ㅜㅜ
: : : :
: : : : Class 는 등록해서 쓰면 되는데,
: : : : LoadPackage 가 Initialize 함수를 찾아 쓰는 건 알겠는데,
: : : : Initialize 함수 처럼 export 하려는데 모르겠네요.

+ -

관련 글 리스트
57552 동적 연결 Package 에 함수 export 하여 사용하는 방법 아루스 802 2009/07/10
57554     Re:동적 연결 Package 에 함수 export 하여 사용하는 방법 아루스 854 2009/07/10
57555         Re:Re:동적 연결 Package 에 함수 export 하여 사용하는 방법 장성호 767 2009/07/10
57558             Re:Re:Re:동적 연결 Package 에 함수 export 하여 사용하는 방법 아루스 860 2009/07/10
57562                 Re:Re:Re:Re:동적 연결 Package 에 함수 export 하여 사용하는 방법 장성호 989 2009/07/10
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.