现在的位置: 首页 > 综合 > 正文

[C语言] 从C++中链接时的C符号的处理

2017年11月13日 ⁄ 综合 ⁄ 共 787字 ⁄ 字号 评论关闭

From wiki: http://zh.wikipedia.org/wiki/%E5%90%8D%E5%AD%97%E4%BF%AE%E9%A5%B0

最常见的C++惯常的做法:

#ifdef __cplusplus 
extern "C" {
#endif
    /* ... */
#ifdef __cplusplus
}
#endif

这种写法用于确保下符号是未被C++编译器名字修饰过的——这种代码能使得C++编译器编译出的二进制目标代码中的链接符号是未经过C++名字修饰过的,就像C编译器一样。就像C语言定义是未名字修饰过的一样,C++编译器需要防止名字修饰这些标识符。

例如,C标准字符串库<string.h>通常包含了类似这样子的

#ifdef __cplusplus
extern "C" {
#endif
 
void *memset (void *, int, size_t);
char *strcat (char *, const char *);
int   strcmp (const char *, const char *);
char *strcpy (char *, const char *);
 
#ifdef __cplusplus
}
#endif

于是,例如这样的代码

if (strcmp(argv[1], "-x") == 0) 
    strcpy(a, argv[2]);
else 
    memset (a, 0, sizeof(a));

就能使用正确的、未经名字修饰过的strcmpmemset。如果没有使用extern "C",那么SunPro C++编译器会产生等价于下面的C代码:

if (__1cGstrcmp6Fpkc1_i_(argv[1], "-x") == 0) 
    __1cGstrcpy6Fpcpkc_0_(a, argv[2]);
else 
    __1cGmemset6FpviI_0_ (a, 0, sizeof(a));

而这些链接符号并不存在于C运行库中(例如 libc)。因此将导致链接错误。

抱歉!评论已关闭.