2014-09-19 53 views
1

下面是一個簡化示例。假設我正在使用庫B和C編寫程序A.可以更改Niether庫的源代碼,並且它們是唯一可用於此目的的庫。圖書館B有一個合理的#define,而圖書館C有一個愚蠢的#define,它將其別名。喜歡的東西說:#define有條件衝突#inc -d庫

//library_b_header.hpp 
#pragma once 
#define uint16 unsigned short 

//... 

//library_c_header.hpp 
#pragma once 
#define uint16 unsigned char 

大部分的先例我就像是this問題。一個答案有益建議,涵蓋了我見過的(意譯)的建議範圍:

  • 添加#undef在自己的代碼
  • 不直接包括library_c_header.hpp。如果另一個庫包含它,請不要直接包含。相反,將其包含在單獨的.cpp文件中,該文件可以在其標頭中顯示包裝函數。
  • 重命名您自己的符號。

第二種選擇接近我的正常解決方案,但庫C是巨大的;我不可能包裝所有的功能。即使我可以,也有很大的可能性,並且它不可移植到庫C的新版本(這也很常見)。

第三個選項不起作用,因爲這在任何地方都可以使用。這不僅僅是,這是相沖突的;它與幾乎一切相沖突。我想可以完成。 。 。它只是一個錯誤錯誤#define,它應該死!

這裏的第一個選項最接近我想要的。第二個問題是庫C 取決於庫B中定義的令牌。

我已經得到最遠的是:

#include <library_b/library_b_header.hpp> 
#define library_b_uint16 uint16 
#undef uint16 

#ifdef LIBRARY_B_SYMBOL 
    #include <library_c/library_c_header.hpp> 
    #undef uint16 
    #define uint16 library_b_uint16 
#endif 

這顯然是不行的,但也許它表達了我的意圖。還有什麼我可以嘗試嗎?

+0

我有點困惑 - 庫C依賴於庫B,但也與庫B衝突? – 2014-09-19 05:23:04

+0

@MichaelBurr這些庫是不相關的,但正在編寫的程序只能包含C,如果符號在B中定義的話。請參閱示例。 – imallett 2014-09-19 05:26:30

回答

3

如果你的編譯器支持push_macropop_macro編譯指示,您可以使用它們像這樣:

#include <library_b/library_b_header.hpp> 

#pragma push_macro("uint16") 
#undef uint16 
#include <library_c/library_c_header.hpp> 
#pragma pop_macro("uint16") 

(這些編譯指示是非標準的,但它們被廣泛支持的Visual C++,GCC,鐺,和英特爾C++編譯器都支持它們。)

是的,您需要在無處不在的位置添加來自定義此宏的庫C的頭文件,但這通常通過編寫自己的頭文件來簡化,該頭文件包含庫C頭文件,然後在您的項目中需要庫C的地方包含該頭文件。

+0

MSVC和g ++的工作就足夠了我的目的。+1教我'push_macro' /'pop_macro'。接受解決問題。謝謝! – imallett 2014-09-19 05:33:30