2012-04-03 57 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