moc 원 개체 컴 파일 러 소개

댓 글 주소:http://news.ccidnet.com/art/32859/20100726/2128903_1.html
http://blog.csdn.net/yong_f/archive/2009/12/29/5098294.aspx
 
Qt 는 '표준 적 인' C + + 언어 가 아니 라 어느 정도 '확장' 을 했 습 니 다.여기 서 우 리 는 Qt 에 새로 추 가 된 키 워드 를 통 해 signals, slots 또는 emit 를 알 수 있다.그래서 Qt 의 프로그램 컴 파일 속도 가 느리다 고 생각 하 는 사람 이 있 습 니 다. 이것 은 주로 Qt 에서 원본 코드 를 표준 C + + 컴 파일 러 에 전달 하기 때 문 입 니 다. 예 를 들 어 gcc 전에 이 확 장 된 문법 을 미리 제거 해 야 하기 때 문 입 니 다.이 조작 을 완성 한 것 은 moc 입 니 다.
 
moc 는 모두 Meta - Object Compiler, 즉 '원 대상 컴 파일 러' 라 고 부른다.Qt 프로그램 은 표준 컴 파일 러 에 의 해 컴 파일 되 기 전에 먼저 moc 를 사용 하여 C + 소스 파일 을 분석 해 야 합 니 다.헤더 파일 에 매크로 Q 가 포함 되 어 있 는 것 을 발견 하면OBJECT 는 다른 C + + 원본 파일 을 생 성 합 니 다.이 원본 파일 에는 Q 가 포함 되 어 있 습 니 다.OBJECT 매크로 구현 코드.이 새 파일 이름 은 원본 파일 이름 앞 에 moc 를 추가 합 니 다.구성이 새 파일 역시 컴 파일 시스템 에 들 어가 바 이 너 리 코드 로 연 결 됩 니 다.따라서 이 새 파일 은 오래된 파일 을 바 꾸 는 것 이 아니 라 원본 파일 과 함께 컴 파일 에 참여 한 다 는 것 을 알 수 있다.또한, moc 의 실행 은 예비 프로세서 이전에 있 음 을 알 수 있 습 니 다.예비 프로세서 가 실행 되면 QOBJECT 매크로 는 존재 하지 않 습 니 다.
 
모든 원본 파일 을 moc 로 처리 해 야 하 는 이상, 우 리 는 언제 그것 을 호출 했 습 니까?실제로 qmake 를 사용 하면 이 호출 은 생 성 된 Makefile 에서 보 여 집 니 다.본질 적 으로 qmake 는 Makefile 생 성기 에 불과 하기 때문에 최종 실행 은 make 를 통 해 이 루어 집 니 다.
 
moc 에서 생 성 된 파일 을 보기 위해 서 간단 한 cpp 를 사용 하여 테스트 합 니 다.
 
test.cpp
class Test : public QObject { Q_OBJECT public: explicit Test(QObject *parent = 0); signals: public slots: };
이것 은 공백 류 로 아무것도 실현 되 지 않 았 다.컴 파일 을 거 친 후에 출력 폴 더 에서 moc 를 찾 을 수 있 습 니 다.test.cpp:
 
 
 
moc_test.cpp

/****************************************
Meta object code from reading C++ file 'test.h' ** *
* Created: Thu Jul 22 13:06:45 2010 **      
by: The Qt Meta Object Compiler version 62 (Qt 4.6.3) ** 
WARNING! All changes made in this file will be lost! **
******************************************
/  #include "../test.h" #if !defined(Q_MOC_OUTPUT_REVISION)
 #error "The header file 'test.h' doesn't include <QObject>."
 #elif Q_MOC_OUTPUT_REVISION != 62 #error 
"This file was generated using the moc from 4.6.3. It" 
#error "cannot be used with the include files from this version of Qt." 
#error "(The moc has changed too much.)" 
#endif  QT_BEGIN_MOC_NAMESPACE 
static const uint qt_meta_data_Test[] = {   
// content:        4,       // revision        0,       
// classname        0,    0, // classinfo        0,    0, 
// methods        0,    0, // properties        0,    0, 
// enums/sets        0,    0, // constructors        0,       
// flags        0,       // signalCount         0        
// eod };  
static const char qt_meta_stringdata_Test[] = {     
"Test/0" };  const QMetaObject Test::staticMetaObject = { 
    { &QObject::staticMetaObject, qt_meta_stringdata_Test,      
 qt_meta_data_Test, 0 } };  
#ifdef Q_NO_DATA_RELOCATION
 const QMetaObject &Test::getStaticMetaObject() 
{ return staticMetaObject; } #endif
//Q_NO_DATA_RELOCATION  
const QMetaObject *Test::metaObject() const {  
   return QObject::d_ptr->metaObject ?
 QObject::d_ptr->metaObject : &staticMetaObject; }  
void *Test::qt_metacast(const char *_clname) {   
  if (!_clname) return 0;     
if (!strcmp(_clname, qt_meta_stringdata_Test))
  return static_cast<void*>(const_cast< Test*>(this));  
return QObject::qt_metacast(_clname); }  
int Test::qt_metacall(QMetaObject::Call _c, int _id, void **_a) {   
  _id = QObject::qt_metacall(_c, _id, _a);     if (_id < 0)       
  return _id;     return _id; } QT_END_MOC_NAMESPACE

보 입 니 다. moctest. cpp 에 Test 류 에 많은 함 수 를 추가 하 였 습 니 다.그러나 우 리 는 이 함수 들 을 실제로 쓰 지 않 았 습 니 다. 그것 은 어떻게 종 류 를 넣 었 습 니까?잊 지 마 세 요. 우 리 는 Q 가 있 습 니 다.OBJECT 이 매크로 는!qobject defs. h 에서 Q 를 찾 습 니 다.OBJECT 매크로 의 정의:
 
 
 
#define Q_OBJECT / public: /     Q_OBJECT_CHECK /  
   static const QMetaObject staticMetaObject; /    
 Q_OBJECT_GETSTATICMETAOBJECT / 
    virtual const QMetaObject *metaObject() const; /   
  virtual void *qt_metacast(const char *); /   
  QT_TR_FUNCTIONS /     
virtual int qt_metacall(QMetaObject::Call, int, void **);
 / private:

이제 알 겠 습 니 다: 바로 QOBJECT 매크로 의 전개 로 인해 우리 의 Test 류 는 이러한 많은 속성 과 함 수 를 가지 게 되 었 다.주의, QTTR_FUNCTIONS 라 는 매크로 도 여기 서 정의 합 니 다.즉, tr () 국제 화 를 사용 하려 면 Q 를 사용 해 야 한 다 는 것 이다.OBJECT 매크로, 그렇지 않 으 면 tr () 함수 가 없습니다.그 동안 가장 중요 한 것 은 virtual const QMetaObject * metaObject () const 입 니 다.함수이 함 수 는 QMetaObject 메타 대상 클래스 의 인 스 턴 스 를 되 돌려 줍 니 다. 이 를 통 해 Qt 클래스 의 반사 능력 을 얻 을 수 있 습 니 다. 이 대상 의 유형 과 같은 것 을 가 져 옵 니 다. 이 모든 것 은 C + 컴 파일 러 의 RTTI 지원 이 필요 하지 않 습 니 다.Qt 도 C + + 와 유사 한 dynamic 를 제공 합 니 다.cast () 의 함수 qobjectcase (), 이 함수 의 실현 도 RTTI 가 필요 하지 않 습 니 다.또 하 나 는 정의 되 지 않 은 QOBJECT 매크로 의 클래스 는 가장 가 까 운 부모 클래스 와 같은 유형 입 니 다.즉, A 가 QObject 를 계승 하고 Q 를 정의 하면OBJECT, B 는 A 를 계 승 했 지만 정 의 를 내리 지 않 았 다 QOBJECT, C 가 B 를 계승 하면 C 의 QMetaObject:: className () 함 수 는 자신의 이름 이 아 닌 A 로 돌아 갑 니 다.따라서 이 문 제 를 피하 기 위해 서 는 QObject 를 계승 한 모든 클래스 가 Q 를 정의 해 야 합 니 다.OBJECT 매크로, 신호 슬롯 을 사용 하 든 말 든.

좋은 웹페이지 즐겨찾기