【问题标题】:C2732 - Linkage specification errorC2732 - 链接规范错误
【发布时间】:2013-11-22 07:45:01
【问题描述】:

我正在使用 VS2008。我收到以下错误。

BUILD: [02:0000000295:ERRORE] c:\wince700\platform\am33x_bsp\src\bootloader\bootpart\bootpart_e.cpp(61) : error C2732: linkage specification contradicts earlier specification for 'SdhcInitialize' {log="C:\WINCE700\platform\AM33X_BSP\SRC\BOOTLOADER\bldsys.log(103)"}
BUILD: [02:0000000297:ERRORE] NMAKE : fatal error U1077: 'C:\WINCE700\sdk\bin\i386\ARM\cl.EXE' : return code '0x2' {log="C:\WINCE700\platform\AM33X_BSP\SRC\BOOTLOADER\bldsys.log(104)"}
BUILD: [02:0000000299:ERRORE]  clean TargetCompilePass  -nologo BUILDMSG=Stop.  BUILDROOT=C:\WINCE700\platform\AM33X_BSP CLEANBUILD=1 NOLINK=1 NOPASS0=1 failed - rc = 2. {log="C:\WINCE700\platform\AM33X_BSP\SRC\BOOTLOADER\bldsys.log(105)"}

file_1.cpp

extern "C"
{
   // some extern declarations
   extern void SdhcInitialize(DWORD slot);
}

file_2.c

void SdhcInitialize(DWORD slot)
{
//some code
}

请指导我如何解决。

【问题讨论】:

  • 什么是SD_API_STATUS?错误日志中是否写了更多内容?请更新问题以包含完整(且未经编辑的)日志。
  • 你确定没有SdhcInitialize的其他声明/定义?
  • 我假设这是一个状态码返回类型,而不是带有声明说明符的宏。
  • @JoachimPileborg 这只是一个结构。但是,为简单起见,我用void 更新了我的问题。此外,我还包括了未经编辑的日志。谢谢。
  • 您的其他声明是否缺少extern 或有static?您是否在.cpp 文件中包含.c 文件(例如某些C++ 文件中的#include "file_2.c"). Why not have header file_2.h` 以及需要的extern 声明,这些声明将包含在其他文件中,而不是在整个文件中都包含externs像你现在这样的地方?

标签: c++ c visual-studio-2008 extern


【解决方案1】:

我猜你有一个包含SdhcInitialize() 函数原型的标头,并且标头是为 C 程序使用而编写的。因此,例如,头文件可能包含类似于以下行的内容:

SD_API_STATUS SdhcInitialize(DWORD slot);

没有包含在 extern "C" {} 块中(因为标头是为 C 程序设计的)。

此外,我怀疑 file_1.cpp 直接或间接包含了此标头

这意味着如果不做一些额外的工作,头文件就不能包含在 C++ 程序中,否则 C++ 程序会将声明视为意味着 SdhcInitialize() 具有 C++ 链接。

你有两种合理的方法来解决这个问题:

  • 如果您可以修改标题,请在标题中的声明周围添加以下行:

      #if __cplusplus
      extern "C" {
      #endif
    
      // declarations go here
    
      #if __cplusplus
      }
      #endif
    

    这样,C++ 文件的声明将包含在 extern "C" 链接块中,而 C 程序将看不到 extern "C" 位(否则会混淆 C 编译器)。

    我认为可以提出一个论点,即所有 C 头文件都应包含类似这些行的内容,以便 C++ 程序可以轻松使用 C 函数。

  • 如果由于某种原因无法修改标头,您可以通过在 C++ 文件中包含标头来解决此问题,如下所示:

      extern "C" {
      #include "Sdhc-header.h"
      }
    

【讨论】:

  • 谢谢。如前所述,我已包含__cplusplus,但错误仍然存​​在。你提到了I suspect that this header is being included - directly or indirectly - by file_1.cpp。实际上,我有另一个具有.c 扩展名的文件,其中我刚刚声明了没有“C”的extern。这个错误背后有什么原因吗?
  • bootpart_e.cpp 是否包含一些声明 SdhcInitialize() 的文件(包括间接)。如果您无法确定这一点,使用/P 选项会将预处理器输出发送到一个文件,您可以在该文件中搜索SdhcInitialize 的所有实例以查看声明的来源。
【解决方案2】:

如果你用extern "C" { ... }包围一组函数声明,你不需要在函数标识符前使用额外的externkeyword。

extern "C"
{
   // some extern declarations
   SD_API_STATUS SdhcInitialize(DWORD slot);
}

【讨论】:

  • 谢谢。但是,即使删除该 extern 也不会对该错误进行任何更改。
  • 我得到了同样的警告,当我使用“双重外部”时,当我删除一个外部时警告消失了,但是为什么?,extern "C"extern 不同?
【解决方案3】:

当您尝试在“C++ 文件”中包含“C 的一些头文件”文件时(头文件有一些 extern "C" 用于某些功能)。

早点包含标题会解决问题。

例如尝试将 #include "myHeader.h" 移动到 C++ 文件的顶行。

这解决了我的问题。

希望对你有帮助....

【讨论】:

  • 这对我有用,谢谢! (虽然我真的不知道为什么Q_Q)
【解决方案4】:

我已经解决了这个问题(其他解决方案对我不起作用):

在文件vector.cc中:

#define __INVECTOR //solves 
#include "vector.h"

在vector.h中:

#ifndef __INVECTOR
void function(...etc..);
#endif

除非我们想从不同的文件中调用函数,否则不会读取声明。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 2010-12-30
    • 2015-10-30
    • 1970-01-01
    • 2016-06-16
    • 2012-04-10
    • 2014-03-25
    相关资源
    最近更新 更多