2012-04-03 91 views
1

我正在處理一個具有多個文件的項目,我需要在每個項目中進行登錄。如何避免PANTHEIOS_FE_PROCESS_IDENTITY的多重定義?

爲了編譯一個文件,我需要如下:

/* Define the stock front-end process identity, so that it links when using 
* fe.N, fe.simple, etc. */ 
PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PSTR("fileX.cpp"); 

比方說,我有log1.cpp和log2.cpp和log.h常見的兩種文件。這些文件被編譯爲log1.o和log2.o.這工作得很好。

現在,當我將這兩個文件鏈接成一個可執行文件,我得到以下錯誤:

log2.o:(.rodata+0x11): multiple definition of `PANTHEIOS_FE_PROCESS_IDENTITY' 
log1.o:(.rodata+0x45): first defined here 

現在的問題是,PANTHEIOS_FE_PROCESS_IDENTITY需要在這兩個file1.cpp和file2.cpp中被定義爲了編譯。

如何更改我的代碼以便能夠將其鏈接到可執行文件?

以下是所使用的文件: log1.cpp:

#include "log.h" 

const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PSTR("log1.cpp"); 

int main() 
{ 
    PANTHEIOS_TRACE_NOTICE(PSTR("a string at NOTICE level")); 
    return 0; 
} 

log2.cpp:

#include "log.h" 
const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PSTR("log1.cpp"); 

log.h:

#ifndef LOG_H 
#define LOG_H 

/* Pantheios Header Files */ 
#include <pantheios/pantheios.h>    // Pantheios C main header 
#ifndef STLSOFT_CF_SUPPORTS_VARIADIC_MACROS 
# error This example uses the Tracing API, which requires that the compiler support variadic macros 
#endif /* !STLSOFT_CF_SUPPORTS_VARIADIC_MACROS */ 
#ifdef STLSOFT_CF_FUNCTION_SYMBOL_SUPPORT 
# include <string> 
# define PANTHEIOS_TRACE_PREFIX  \ 
    ( std::basic_string< PANTHEIOS_NS_QUAL(pan_char_t)>(__FILE__ " " PANTHEIOS_STRINGIZE(__LINE__) ": ") + \ 
     __FUNCTION__ + \ 
     "(): " \ 
    ).c_str() 
#endif /* STLSOFT_CF_FUNCTION_SYMBOL_SUPPORT */ 
#include <pantheios/trace.h>     // Pantheios Trace API 
#include <pantheios/pantheios.hpp>    // Pantheios C++ main header 

/* Standard C/C++ Header Files */ 
#include <exception>       // for std::exception 
#include <new>         // for std::bad_alloc 
#include <string>        // for std::string 
#include <stdlib.h>        // for exit codes 

#ifndef PANTHEIOS_DOCUMENTATION_SKIP_SECTION 
# if defined(STLSOFT_COMPILER_IS_MSVC) 
# pragma warning(disable : 4702) 
# endif /* compiler */ 
#endif /* !PANTHEIOS_DOCUMENTATION_SKIP_SECTION */ 

#define PSTR(x)   PANTHEIOS_LITERAL_STRING(x) 

#include "pantheios/frontends/fe.simple.h" //for pantheios_fe_simple_setSeverityCeiling(level); 

#endif //LOG_H 

做優做強的輸出:

g++ log1.cpp -c -I../pantheios-1.0.1-beta213/include -I../stlsoft-1.9.112/include 
g++ log2.cpp -c -I../pantheios-1.0.1-beta213/include -I../stlsoft-1.9.112/include 
g++ -o log log1.o log2.o -L../pantheios-1.0.1-beta213/lib \ 
     -lpantheios.1.core.gcc44\ 
     -lpantheios.1.be.fprintf.gcc44 -lpantheios.1.bec.fprintf.gcc44\ 
     -lpantheios.1.fe.simple.gcc44 -lpantheios.1.util.gcc44 
log2.o:(.rodata+0x0): multiple definition of `PANTHEIOS_FE_PROCESS_IDENTITY' 
log1.o:(.rodata+0x1): first defined here 
/usr/bin/ld: Warning: size of symbol `PANTHEIOS_FE_PROCESS_IDENTITY' changed from 14 in log1.o to 9 in log2.o 
collect2: ld returned 1 exit status 

編輯:在pantheios-1.0.1-beta213/include/pantheios/frontends/stock.h中:120'PANTHEIOS_FE_PROCESS_IDENTITY'被聲明爲extern,所以我不能將它重新定義爲靜態。

回答

2

我道歉,如果我的提問/回答聽起來很奇怪:但爲什麼要在每個.cpp文件來定義PANTHEIOS_FE_PROCESS_IDENTITY? PANTHEIOS_FE_PROCESS_IDENTITY只需在每個日誌記錄過程中定義一次,並在每行開始時打印到日誌語句中。例如。從我自己的基於pantheios的記錄器項目:

[l.SPP.6408,4/7/2012 6:28:44.702 PM;注意]:。\ Log.cpp(168):CLogApp :: InitInstance:啓動日誌

我只有1個PANTHEIOS_FE_PROCESS_IDENTITY定義 - 在Log.cpp中(而不是.h)。如下,適用於不僅是LOG的項目,但在我的解決方案(VS2005)需要訪問記錄器等項目:

PANTHEIOS_EXTERN_C const char PANTHEIOS_FE_PROCESS_IDENTITY[] = "l.SPP";

你會得到的文件名+行號從哪裏日誌語句正在打印出來,如果您使用PANTHEIOS_TRACE_NOTICE - 請參閱上面張貼的示例(粗體)。

我建議您確定PANTHEIOS_FE_PROCESS_IDENTITY是否真的需要按per-cpp文件或per-project定義 - 我的經驗表明後者是答案。

0

這取決於PANTHEIOS_EXTERN_C擴展到的範圍。如果它擴大到extern - 很可能 - 你會得到錯誤。

我要麼完全刪除它或取消定義它。 (我會去與第一位的,沒有必要爲它是extern

注意,在這種情況下,PANTHEIOS_FE_PROCESS_IDENTITY是不是一個全球性的。如果你想讓它全局的,你把它聲明爲extern 只有在翻譯單元的一個定義它

這樣:

如果PANTHEIOS_FE_PROCESS_IDENTITY應該是全球性的:

//log1.cpp 

const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PSTR("fileX.cpp"); 
//definition here 

//log2.cpp 

PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[]; 
//declared as extern here 

如果沒有,你想它的2個文件不同:

//log1.cpp 

const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PSTR("fileX.cpp"); //not extern 
                     //definition 

//log2.cpp 

const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PSTR("fileX.cpp"); //not extern 
                     //definition 
+0

我想要第二個log1.cpp的X = 1和log2.cpp的2。當我刪除PANTHEIOS_EXTERN_C時,仍然出現多重定義錯誤。 – Burkhard 2012-04-03 14:54:17

0

如果你想在一個const PANTHEIOS_FE_PROCESS_IDENTITY文件,file1.cpp,另有const PANTHEIOS_FE_PROCESS_IDENTITY在另一個文件中,file2.cpp,然後把它聲明爲static它不會被導出到文件之外。

PANTHEIOS_EXTERN_C static const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PSTR("fileX.cpp"); 
+0

甚至沒有編譯:「log1.cpp:6:錯誤:在鏈接規範中無效使用'static' – Burkhard 2012-04-03 15:08:36