C ++:全局范围内的变量声明与C语言链接的声明冲突

时间:2017-03-03 13:03:58

标签: c++ xcode c++11 extern linkage

我有一些InDesign插件的遗留代码,我正在尝试编译新版本的InDesign,它使用C ++ 11支持的XCode编译器。

有一个头文件AdWrksSession.h,它包含一个具有C链接的类对象,如下所示。 正如extern对象/变量的声明:

extern "C" CAdWrksSession gAdWrksSession;

并且cpp文件AdWrksSession.cpp包含一个全局类对象,其默认构造函数与extern对象同名:

CAdWrksSession gAdWrksSession;

较旧的编译器没有显示任何错误消息但是当它与Apple为XCode 7.2.1提供的新编译器一起使用时,它支持C ++ 11,它向我显示以下错误:

Declaration of 'gAdWrksSession' in global scope conflicts with declaration with C language linkage

我尝试过针对C链接的已问问题:

Compiler error for conflicting variable declarations: "conflicts with new declaration with 'C' linkage"

What is "extern linkage and with C language linkage"

Mixing declarations with extern, static and no storage specifier in global scope

我在header文件中尝试了以下外部变量声明的语法:

#ifdef __cplusplus
   extern "C" {
#endif
        CAdWrksSession gAdWrksSession;
#ifdef __cplusplus
    }
#endif

#ifdef COMPILE_FOR_C_LINKAGE
     extern "C" CAdWrksSession gAdWrksSession; 
#else
     extern "C++" CAdWrksSession gAdWrksSession;
#endif

但到目前为止还没有任何工作。

当我将header文件声明设为static

static CAdWrksSession gAdWrksSession; //Header File

然后代码构建成功,但该功能当然不起作用。

更新 如果我删除C链接,那么我得到一个链接器错误如下:

Undefined symbols for architecture x86_64:
  "smart::gAdWrksSession", referenced from:
....//Names of generated object files
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 
(use -v to see invocation)`

有人可以帮我吗?感谢。

1 个答案:

答案 0 :(得分:0)

我认为如果CAdWrksSession实际上是一个类而不是一个不透明指针,则忽略在标题中使用的extern "C"。关于extern "C"行为的this堆栈溢出问题有一些讨论。

确保标题是C的唯一方法是将标题包含在虚拟main.c中并尝试将库链接到它。 (如果您想对此进行更多澄清,请告诉我们)

然而,也许我们可以找到另一种方法来解决您的问题。我不知道你对这个插件的限制。我建议你创建一个代理库,它是一个共享对象,它与私有代码(如果可能的话,静态地)链接到遗留代码。这是,将代理设计模式see API section book 3.4.1应用于您需要公开的所有类。

然后,您可以使用此代理库创建新代码链接,这样您就不会发生名称冲突。