2009-05-26 107 views
0

我正在從Visual Studio 6遷移到Visual Studio 2008,並且我有一個使用名爲SetDefaultPrinter的組件的功能。預處理程序忽略

不幸的是,現在有一個windows庫函數,SetDefaultPrinter,具有相同的名稱。與此相關的宏正在妨礙我使用我的功能。

這是我的解決辦法我有打電話給我的功能:

#undef SetDefaultPrinter 
    pNova->SetDefaultPrinter(); 
#ifdef UNICODE 
#define SetDefaultPrinter SetDefaultPrinterW 
#else 
#define SetDefaultPrinter SetDefaultPrinterA 
#endif // !UNICODE 

有沒有解決這個不那麼醜陋的方式?不,我無法控制該外部組件來更改函數的名稱。

回答

3

這就是C++添加命名空間的原因; Windows定義不能使用它們太糟糕了。

在另一個源模塊中,如果不包含windows.h或任何其他Windows包含文件,則生成存根函數以調用您的碰撞函數。

void MySetDefaultPrinter(CNova * pNova) 
{ 
    pNova->SetDefaultPrinter(); 
} 
+0

不幸的是,微軟在這裏設法使命名空間毫無用處,因爲幾乎整個Win32 API都變成了宏。 SetDefaultPrinter是一個宏(映射到SetDefaultPrinterA或SetDefaultPrinterW),因此名稱不會遵守命名空間範圍。 在一個充滿糟糕設計和WTF時刻的API中,這必須是最大的一個。不幸的是,似乎我們一直在堅持下去。 – jalf 2009-05-26 22:09:27

1

您可以在外部組件上使用包裝。這有時被稱爲"Adapter" pattern

// header file 
class NovaWrapper 
{ 
    Nova *_nova; 
    public: 
    void setDefaultPrinter(); 
}; 

// implementation file - this file does not include windows.h - you need to make sure it 
// does not have visibility of the "bad" SetDefaultPrinter macro 
void NovaWrapper::setDefaultPrinter() 
{ 
    _nova->SetDefaultPrinter(); 
} 

現在,修改您的客戶端代碼以使用NovaWrapper而不是底層實例。

0

這是最後,通過簡單地交換包含的順序來修復。顯然,這個組件的開發人員在我之前意識到了這個問題,所以他們在SetDefaultPrinter的組件中包含了SetDefaultPrinterASetDefaultPrinterW。所以,如果windows.h重命名該函數,這不是一個問題。