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
[66253] Re:Re: 빌더님 강좌 좀 부탁 드립니다 ^^
대박왕 [] 1297 읽음    2012-02-13 12:42
답변해 주시는 글들 음미하면서 잘보고 있는 눈팅이 입니다 ^^;;;
빌더님!!!!!! 강좌 좀 해주세여~~~
정중하게 부탁 드립니다~~ 헤헤 ^^;;;;;;;;;




빌더 님이 쓰신 글 :
: 왕초보와코드 님이 쓰신 글 :
: : C++빌더에서 사용하는 VCL컨트롤들은 델파이로 만들어 진 것으로 알고 있습니다.
: :
: : 그리고 추가로 설치하는 컴포넌트들도 사실 델파이로 만들어진 것이 많이 있죠.
: :
: : 갑자기 의문이 생기는데, 추가 설치하는 컴포넌트들은 델파이로 코드가 만들어져 있고,
: :
: : 가져와서 직접 컴파일한후, 인스톨해서 사용하는 경우가 많이 있는데, 이런 점으로 봐서
: :
: : 분명 빌더는 델파이 코드를 컴파일하는 능력이 있다는 이야기 입니다.
: :
: :
: : 그렇다면,
: :
: : 1) 델파이 제품 또는 Rad Studio와 C++빌더 단일제품의 차이점은 무엇일까요?
: :
: : 2) 진짜 C++빌더만 가지고도 델파이 코딩이 가능한가요?
: :
: :
: : 해보신 분 있나요?
:
:
:
:
:
:
:
: 답변...
:
:
: 이 문제는 델파이로 짜여진 VCL 소스코드를 C++ 로 완전하게 포팅하는게 가능하냐 하는 것과도 연관이
: 있는 부분이라, 먼저 이 부분 부터 짚어 보겠습니다.
:
: 델파이 개발환경의 강점은 Rapid Application Development 환경이란 거고, Form Designer 를 통해서
: VCL 콘트롤을 동적으로 생성하고, Object Inspector 로 Property 값을 바꾸기도 하고, 폼에서 삭제하면
: 객체를 소멸 시키기도 하는 건데요.
:
: 이렇게 Design Time 시에 Dynamic 한 객체 사용이 가능한 것은 델파이 컴파일러가 생성하는 확장된
: RTTI 정보 때문 입니다. 예를 들어 보죠.
:
: Design Time Package 의 코드 프레임은 예를 들면 다음과 같은 식으로 구성 됩니다.
:
:
: 
: namespace MyDesignTimeComponent
: {
:     void __fastcall PACKAGE Register()
:     {
:          TComponentClass classes[1] = {__classid(TMyButton)};
:          RegisterComponents(L"MyComponent", classes, 0);
:     }
: }
: 
: 
: 

:
: 패키지 자체에서는 컴포넌트를 생성하는 코드 부분이 없습니다. 그저 위와 같은 식으로 TMyButton
: 클래스의 Type 정보만 RegisterComponents 함수로 넘겨줄 뿐인데요..
:
: 컴파일 후.. Register 함수는 .BPL 파일의 Export 섹션에 엔트리로 노출되게 됩니다.
:
: 그렇기 때문에 RAD IDE 개발환경이 Design Time Package 파일을 로드할 때... .BPL 파일에서 정의된
: Register 펑션을 호출 할수 있게 되죠.
:
: RegisterComponents 펑션은 System.Classes.pas 에 아래와 같은 식으로 정의 되어있습니다.
:
:
: 
: procedure RegisterComponents(const Page: string;
:   ComponentClasses: array of TComponentClass);
: //  const ComponentClasses: array of TComponentClass);
: begin
:   if Assigned(RegisterComponentsProc) then
:     RegisterComponentsProc(Page, ComponentClasses)
:   else
:     raise EComponentError.CreateRes(@SRegisterError);
: end;
: 
: 
: 

:
:
: 여기서 RegisterComponentsProc 는 이 유닛에서 nil 값으로 되어있는 함수 포인터 입니다.
: 그런데 VCL 소스코드를 뒤져 보면... nil 값을 갖고있는 RegisterComponentsProc 에 함수의
: 주소를 대입해 주는 코드는 어느 곳에서도 전혀 보이지 않습니다.
:
: 사실상 RegisterComponentsProc 는 rtl160.bpl 파일에서 ord 넘버 4615 를 갖는  함수로
: Export 되어 있습니다.(Embarcadero 애들이 그런식으로 컴파일 해서 배포를 했다는 거죠.)
: 그렇기 때문에 개발환경의 패키지 로더가 RegisterComponentsProc 함수 포인터의 주소를 알수 있고
: Startup 과정에서 이 함수포인터를 IDE 개발환경의 패키지 로더가 자신의 어느 부분의 주소 값으로
: 함수포인터를 패치 하게 됩니다.
:
: RegisterComponentsProc 함수포인터가 호출되게 되면, 결과적으로 IDE 환경의 패키지 로더 내부함수
: 가 호출되게 되고, TMyButton 클래스의 ClassType 정보가 이런 식으로 패키지 로더(폼 디자이너)에
: 알려지게 됩니다.
:
: __classid(TMyButton) 은 컴파일러가 생성해준 해당 클래스에 대한 TypeInfo 테이블에 대한 포인터를
: 리턴하는데(테이블의 다양한 섹션 중에서 VMT를 zero 베이스로 사용 합니다)... TypeInfo 테이블에 대한
: 구체적인 자료구조와 RTTI, VMT 테이블 과의 연관 관계는 언제 기회가 되면 강좌를 통해서 다뤄 보도록
: 하고요.
:
: Form Designer 가 다이나믹 하게 VCL 콘트롤을 생성하는 실제적인 내부 코드를 슈도 코드로 나타내
: 보면 다음과 같습니다.
:
: classType은 Dynamic Function Table, VMT, Class Name, Size, Property Name 등의 각종 정보
: 로 구성되어있고, TObject::NewInstance, TObject::FreeInstance 등의 델파이에서 Root Class 로
: 사용되는 TObject 에서 정의된 함수들에 대한 주소 정보도 갖고 있습니다. __classid는 이와 같은
: 정보 테이블의 위치를 알려줍니다. (이 부분도 다음에 강좌를 통해서 자세하게 다뤄보는 기회를 가져
: 보도록 하죠)
:
: 간략하게 폼디자이너의 내부코드를 슈도코드로 나타내 보면...
:
:
: 
: // 패키지 로딩과정에서 얻은 클래스 타입 정보.
: classType = __classid(TMyButton)   
:                          
: // 클래스 객체를 생성하기 위해 메모리를 할당하고, Self 포인터를 VMT 테이블로 
: // 디퍼런싱 하게 되지만 아직 constructor가 호출되지는 않은 단계
: 
: TComponent *instance = classType.NewInstance 
: 
: 
: // TForm을 포함해서 모든 Visual 또는 Non Visual VCL 콘트롤들은 TComponent 로 부터 
: // 상속 받게 되어 있기 때문에, 다음과 같이 constructor를 호출 합니다.
: 
: // 생성자의 실제 호출은 VMT 테이블을 통해서 결정되기 때문에, 컴파일러는 VMT 테이블의 
: // Index를 갖고, constructor를 호출하는 코드를 생성 하게 됩니다.
: 
: instance.Create(Self)  
: 
: 
: 

:
:
: 여기서 델파이와 C++ 과의 극명한 차이가 드러나는 데요. 델파이에선 construcor 네임을 사용자가
: 마음대로 정할 수도 있고, 또 일반 함수처럼 명시적으로 호출하는 것도 가능 합니다. 그러나 C++에선
: 이게 허용되지 않죠.
:
: 그리고 클래스 상속계층에서 끝단에 있는 생성자를 호출해서 객체를 초기화 해야하기 때문에...
: 델파이는 consturctor를 Virtual 함수처럼 다룰 수 밖에 없습니다.
:
: C++과 달리 델파이가 NewInstance 로 객체를 위한 메모리를 할당 하고.. 바로 Virtual Method Table의
: Context를 결정하는 이유도... ClassType 정보 만으로 객체를 다이나믹하게 생성하기 위한 과정에서...
: Late Binding이 필요하고, 그래서 constructor를 일반 Virtual 함수처럼 동작하게 만들 수 밖에 없기
: 때문 입니다.
:
:
: C++에선 명시적으로 constructor 를 사용자가 호출하는 것을 허용하지 않기 때문에, 위와 같은 식의
: 코드패턴을 C++로 바로 포팅할 수는 없습니다. (VCL 소스에선 위와 같은 코드패턴이 곳곳에서 발견
: 됩니다.)
:
: C++로 포팅하기 위해선...
:
: 컴파일러가 생성한 클래스 타입정보 테이블을 갖고, constructor 에 해당하는 VMT 테이블의 인덱스
: 를 찾아서 해당 생성자의 주소, 그리고 전달되는 파라미터의 갯수 그리고 속성을(이런 정보도 테이블
: 에 포함되어 있습니다.) 알아내서.. 런타임 중에 스텍 프레임을 구성해서 간접적으로 호출해주는 코드를
: 구현해 줘야 합니다.
:
: __classmethod  키워드로 정의되는 클래스 메소드 함수도  델파이에선 가능한 record 타입의
: class method는 아직 C++빌더가 지원하지 않고 있습니다. 
:
: C++ 빌더로는 델파이로 컴파일 되어있는 바이너리를 투명하게 사용할 수 있다는 거고...
:
: 델파이로 작성되어 있는 VCL 또는 RTL 소스코드를 C++로  포팅하는 것은 가능은 하지만...
: 노가다가 많이 필요 합니다. C++빌더 컴파일러가 파스칼 소스코드를 컴파일 할수 있는 능력도 갖고 있는
: 것은 아닙니다. 파스칼 소스의 컴파일은 DCC32가 하게 되는 거죠.
:
: 어떻게 적다 보니까... 두서없이 적었네요.. --;

+ -

관련 글 리스트
66245 C++빌더에서 델파이 코드 사용 관련 의문 왕초보와코드 971 2012/02/12
66247     Re: 컴파일러와 개발환경의 내부적인 측면을 살펴 보면... 빌더 1361 2012/02/13
66253         Re:Re: 빌더님 강좌 좀 부탁 드립니다 ^^ 대박왕 1297 2012/02/13
66246     Re:C++빌더에서 델파이 코드 사용 관련 의문 Lyn 1140 2012/02/12
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.