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

델파이 Q&A
Delphi Programming Q&A
[16009] Re:Re:C++빌더님. 불가능할 것 같긴한데요, 혹시나 해서 여쭈어 봅니다
코딩 [] 1438 읽음    2019-03-06 19:08
많은 걸 생각하게 되네요
내공이 부럽습니다 ^^;;;;;

감사합니다


빌더(TWx) 님이 쓰신 글 :
: 코딩 님이 쓰신 글 :
: : procedure f(var v);
: : begin
: :
: : end;
: :
: : procedure TForm1.Button1Click(Sender: TObject);
: : var
: :     str: string;
: :     i: integer;
: : begin
: :     i := 777;
: :     str := 'hello';
: :     f(i);
: :     f(str);
: : end;
: :
: :
: : v가 타입 없는 var로 되어 있는데요
: :
: : 프로시져 f 에서 v 의 타입이 string 인지 integer 인지 알수 있는 방법이 있을까요?
: :
: : 델마당에 올라온 질문인데요
: : 제 생각으론 아무리 생각해봐도 불가능 할것 같긴한데요
: : 혹시나 해서 여쭈어 봅니다.
: :
:
:
:
: 답변:
:
:
: 도움말만 봐도 알수 있는 단순한 컴포넌트 사용법 관련된 글이면 한번 읽고 지나쳤을 텐데...
: 기술적인 부분이라 답변 글 남깁니다.
:
:
: CPU의 고유한 ID 값을 알아내기 위해 메인보드의 롬바이오스 SMB Bios 펌웨어 테이블 파싱이 필요하고
: 펌웨어 테이블의 자료구조 상... 테이블 파싱을 위해 T** two pointer 타입의 포인터 연산이 자주 사용되는데
:
: C++에선 T1 ** 타입을 T2 *& 으로 포인터에 대한 레퍼런스 타입으로 치환해서 포인터 연산을 간략하게 할 수 있으나
:
:      T1 ** p;
:      T2 v = *((T2 *&)p)++;
:
: T** two 포인터 연산을 파스칼로 작성하면 코드가 지져분해지므로 속편하게 예제는 어셈블리 코드로 작성 합니다.
:
:
: Object Inspector 를 통해 다양한 타입을 참조할 수 있는데... Boolean 타입을 예로 들어 봅시다.
: 부울형의 경우 True, False 값을 Object Inspector 에서 표시해 주죠.
: 이와 같은 메카니즘이 가능한 것은 델파이 컴파일러에 의해서 Rtti 정보가 바이너리로 Emit 되기 때문인데요.
: (Object Inspector를 통해서 보여지는 타입 정보들은 컴파일러에 의해 바이너리로 Emit 된 Rtti 정보 중에서
: published 된 극히 일부분에 불과함)
:
: Boolean 타입의 정보를 런타임 중에 바이너리에서 직접 찾아서 표시하는 예를 들어 봅시다.
:
:
: function GetBooleanType(): string;
: type PS = PShortString;
: var tn, v1, v2: DWORD;
: begin
:   asm
:     mov esi, $1000
:     push 0
:     call GetModuleHandle
:     add esi, eax
:     mov esi, [esi]
:     lea esi, [esi + 1]
:     mov tn, esi
:     mov al, [esi]
:     movzx eax, al
:     lea esi, [eax + esi + 14]
:     mov v1, esi
:     mov al, [esi]
:     movzx eax, al
:     lea esi, [eax + esi + 1]
:     mov v2, esi
:   end;
:     Result := 'typeName: ' + PS(tn)^ + ' ,v1: ' + PS(v1)^ + ' ,v2: ' + PS(v2)^;
: end;
: 
: procedure TForm1.Button1Click(Sender: TObject);
: begin
:   Memo1.Lines.Add( GetBooleanType() );
: end;
: 
: 
: 

:
:
:
: 위의 경우는 Boolean 타입 하나만 예로 든 거고...
:
: class, record, virtual method, propery, message handler, event handler, class method, interface method 등등
: 델파이로 컴파일 되어있는 바이너리의 모든 타입 정보들을 리버스 엔지니어링으로 바이너리로 부터 직접 알아 낼수 있지요.
:
:
: 그리고...
:
:
:  procedure f(var v);
:  begin

:  end;

:  procedure TForm1.Button1Click(Sender: TObject);
:  var
:      str: string;
:      i: integer;
:  begin
:      i := 777;
:      str := 'hello';
:      f(i);
:      f(str);
:  end
:
:
:  procedure f(var v); 에서 v 의 타입을 알아내는 건...
:
: 컴파일러에 의해서 타입 정보가 넘어오지 않아서 일견 보기에는 불가능해 보일 수도 있으나
: 넘어온 파라미터 v 가 string 과 integer 둘 중에 하나라는 조건이 주어지고
: 델파이 컴파일러 내부구조를 알고 있으면 이 또한 가능 합니다.
:
:
:
: procedure Foo(var V);
: var mi: array[0..27] of Byte;
: begin
:   asm
:     mov esi, V
:     mov esi, [esi]
:     lea esi, [esi - 12];
:     lea edi, mi
:     push 28
:     push edi
:     push esi
:     call VirtualQuery
:     mov [edi + 16], eax
:     and eax, eax
:     je @skip
:     add esi, 12
:     and dword ptr [edi + 20], $24
:     mov dword ptr [edi + 20], esi
:     je @next
:     cmp dword ptr[esi - 12], $204b0
:     jnz @next
:     mov byte ptr[edi + 16], 2
:     jmp @skip
:   @next:
:     mov byte ptr[edi + 16], 1
:   @skip:
:   end;
: 
:   if mi[16] = 1 then
:     Form1.Memo1.Lines.Add(Format('type: integer, value: %d', [PInteger(@mi[20])^]))
:   else if mi[16] = 2 then
:     Form1.Memo1.Lines.Add(Format('type: string, value: %s', [PChar(PDword(@mi[20])^)]))
:   else
:     Form1.Memo1.Lines.Add('Fail: VirtualQuery()')
: end;
: 
: procedure TForm1.Button1Click(Sender: TObject);
: var
:   s: string;
:   i: integer;
: begin
:   i := 777;
:   s := 'hello';
: 
:   Foo(i);
:   Foo(s);
: end;
: 
: 

:
:
:
:
:
: 모든 코드는 Rad studio 10.3.1 기준으로 작성.
:
:
:

+ -

관련 글 리스트
16006 C++빌더님. 불가능할 것 같긴한데요, 혹시나 해서 여쭈어 봅니다 코딩 1363 2019/02/28
16141     Re:Overload를 사용하시면 쉬울듯.... 첫눈 637 2020/12/08
16007     Re:C++빌더님. 불가능할 것 같긴한데요, 혹시나 해서 여쭈어 봅니다 빌더(TWx) 1752 2019/03/04
16009         Re:Re:C++빌더님. 불가능할 것 같긴한데요, 혹시나 해서 여쭈어 봅니다 코딩 1438 2019/03/06
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.