2009年6月6日星期六

不要被 Windows.h 強暴

引擎的物理部份開始開發,我滿心喜悅地把 Bullet Pyhsics Engine 加入專案,但"咚"的一聲告訴我編譯器掛丟了。誰在作怪呢?當編譯器指向那一向相安無事的數學 max 函數,我就知道是 Bullet include 了 Windows.h。錯就錯在 Bullet 在 btQuickprof.h 哪裡包括了 Windows.h,迫使其他檔案也一併把 Windows.h include 過來,本來潔淨的命名空間就這樣被成千上萬的 macros 如 min, max, CreateWindow, DrawText 等等污染了。
其實 Windows.h 是可以避免在標頭檔中出現的:
  • 盡可能把函數定義由標頭檔移到源碼檔去
  • 大多數基本型別如 DWORD, LARGE_INTEGER 等在標頭檔中可用 unsigned long, __int64 來取代,再在源碼檔用 reinterpret_cast 返回原本的型別。大多數的 struct 指針都可以前置聲明(forward declarate) 如 typedef struct _GUID GUID;
  • 更甚者還會使用 char mMutex[24]; 來取代 CRITICAL_SECTION mMutex; 再加上編譯期 assert 確保兩者內存大小匹配:STATIC_ASSERT(sizeof(mMutex) == sizeof(CRITICAL_SECTION));
把 Windows.h 由標頭檔中抽離以後,不單止命名空間的問題解決了,連編譯的速度都快了哩!

沒有留言:

發佈留言