軟件A中需要集成某音頻引擎B,B引擎庫提供兩個頭文件:B_commontype.h和B_API.h,B_commontype.h中定義引擎用到的基本數據類型,B_API.h中include B_commontype.h文件並定義接口函數,接口函數使用B_commontype.h定義的基本數據類型。
在需要使用該引擎庫函數的Apply_B.cpp文件中將B_commontype.h和B_API.h include進去,
#include "StdAfx.h"
#include "Apply_B.h"
…
#include "B_commontype.h"
#include "B_API.h"
然後調用引擎中提供的函數。
vs編譯時報錯:
B_commontype.h(273) : error C2371: 'int32' : redefinition; different basic types
B_commontype.h(276) : error C2371: 'uint32' : redefinition; different basic types
Apply_B.cpp(801) : error C2664: 'B_GetCodecs' : cannot convert parameter 1 from 'int *' to 'int32 *'
……
分析後瞭解:
該音頻引擎庫在B_commontype.h定義了:
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef int32_t int32;
typedef uint32_t uint32;
項目軟件A在自己的類型定義頭文件A_commonDef.h定義了
#if !defined(int32)
typedef long int32;
#endif
#if !defined(uint32)
typedef unsigned long uint32;
#endif
Apply_B.cpp編譯時候先將A_commonDef.h包含進去,將int32定義爲long類型,接着再將B_commontype.h包含進去編譯,而B_commontype.h將int32定義爲int,所以出現上面描述的編譯錯誤。
可選解決方案:
剛開始考慮將B音頻引擎用一個類封裝起來,這樣B_commontype.h定義的類型和B_API.h定義的接口函數都不公開了,由該封裝類的接口函數代替,如此可避免B和A的int32 uint32定義衝突問題,但是B模塊接口函數太多,這個類實都要一一實現這些接口函數,不堪重負。
後來想到下面這個辦法解決,十行代碼就修改好了,美中不足的是需要修改B模塊的接口頭文件。
具體實現:
在B_commontype.h,如下注釋掉int32和uint32的typedef:
//typedef int32_t int32;
//typedef uint32_t uint32;
這樣工程在編譯B_commontype.h時候,由於int32沒有被定義爲int32_t類型,於是編譯器將int32編譯成A_commonDef.h中定義的long類型和unsigned long類型,
隨後編譯到B_API.h,在B_API.h中的#include "B_commontype.h"語句後緊接着加上:
#define int32 int32_t
#define uint32 uint32_t
這樣在編譯B_commontype.h中的接口函數時候,接口函數用到的int32和uint3都被替換成int32_t和uint32_t,此時的int32_t和int32_t都是B_commontype.h定義下的類型,
在B_API.h文件最後加上:
#undef int32
#undef uint32
來取消前面#define int32 int32_t和 #define uint32 uint32_t的效果
這樣,我們在使用B引擎時候可以保留了接口函數原來時候的類型,而且在A其他地方繼續使用A_commonDef.h定義的類型,A,B不會再在編譯時候產生類型衝突報錯。