Visual Studio 2015:外部“C”和“导出”关键字 我正在努力从VS2012迁移到VS2015的婴儿步骤,我知道,我遇到了一个C标题不再编译的问题,在保留的C++关键词上出错了,即使它们被包含在Ext.C.

Visual Studio 2015:外部“C”和“导出”关键字 我正在努力从VS2012迁移到VS2015的婴儿步骤,我知道,我遇到了一个C标题不再编译的问题,在保留的C++关键词上出错了,即使它们被包含在Ext.C.,c++,c,visual-studio,C++,C,Visual Studio,下面是一个在2012年编译的简化示例,但不是2015年 main.cpp 谢德尔 c测试 编辑: 在创建示例时我犯了一个错误——关键字是导致麻烦的原因是导出——不是我预想的任何C++保留关键字。下面的例子已经修改为使用int导出而不是int新的 < p>新是C++中的关键字。在交叉编译代码中不能将其用作标识符。这就是错误的原因。您必须为变量指定一个不同的名称 注意,将C++翻译单元的一部分放到外部C{}区域并不意味着代码将以某种方式编译为C代码。这仅仅意味着该地区的外部实体将获得C链接。代码本身

下面是一个在2012年编译的简化示例,但不是2015年

main.cpp 谢德尔 c测试 编辑: 在创建示例时我犯了一个错误——关键字是导致麻烦的原因是导出——不是我预想的任何C++保留关键字。下面的例子已经修改为使用int导出而不是int新的

< p>新是C++中的关键字。在交叉编译代码中不能将其用作标识符。这就是错误的原因。您必须为变量指定一个不同的名称

注意,将C++翻译单元的一部分放到外部C{}区域并不意味着代码将以某种方式编译为C代码。这仅仅意味着该地区的外部实体将获得C链接。代码本身仍然是C++代码,所有C++特定的限制仍然适用。< /P> < P>新是C++中的关键字。在交叉编译代码中不能将其用作标识符。这就是错误的原因。您必须为变量指定一个不同的名称


注意,将C++翻译单元的一部分放到外部C{}区域并不意味着代码将以某种方式编译为C代码。这仅仅意味着该地区的外部实体将获得C链接。代码本身仍然被编译为C++代码,所有的C++特定的限制仍然适用。

< P>使用Ext C控制应用的代码的名称的篡改——它不神奇地使编译器编译为C。因此,当包含ExtNint INTITY的头包含时,在.MCP.CPP中,它被编译为C++代码,而导出是C++中的保留字,则会得到语法错误。

< P>使用ExtC控制代码应用的名称的篡改——它不神奇地使编译器将C代码编译为C。因此,当包含ExtNint INTITY的头时,在.cp中,它被编译成C++代码,而导出是C++中的保留字,则会出现语法错误。

进一步挖掘,这里建议的HACK似乎是:

通过以下方式更改main.cpp可以编译它

extern "C" {
    #include "cheader.h"
}

int main()
{
    printfFromC();
    return 0;
}


进一步挖掘,这里的黑客建议似乎有效:

通过以下方式更改main.cpp可以编译它

extern "C" {
    #include "cheader.h"
}

int main()
{
    printfFromC();
    return 0;
}



@ NaNaLover我在创建示例时犯了一个错误——关键字是麻烦的原因是出口——不是我预想的任何C++保留关键字。出口也是C++中的保留词@ NeilButterworth是的,但是区别是这个例子现在编译在2012。因为你的古编译器不支持C++ 11标准。请参阅:NaNaulver我在创建示例时犯了一个错误,关键字是麻烦的原因是出口——不是我预想的任何C++保留关键字。出口也是C++中的保留词@ NeilButterworth是的,但是区别是这个例子现在编译在2012。因为你的古编译器不支持C++ 11。标准正确。请参阅:这并不能解释为什么它在VS2012中编译-我正在迁移的应用程序引用了包含这些关键字的C库标头。之所以编译,是因为VS2012不正确支持C++11标准。这并不能解释为什么它在VS2012中编译-我正在迁移的应用程序引用了包含这些关键字的C库标头关键字。它之所以编译是因为VS2012不正确支持C++11标准。是的,毫不奇怪,将导出名称更改为其他名称将解决问题。但只有当原始名称从未在任何地方使用时,在这种情况下为什么不将其全部删除?不,它不起作用,因为它只影响外部声明,而不影响变量定义。现在,ExtExt导出变量是未定义的。@ Ant:不确定你的观点是什么,它改变了由关键字定义的变量名的名称,但实际上并不影响C++应用程序所使用的任何东西,因为它无论如何都不能使用这些名称。这允许它进行编译。任何与它动态链接的东西都会像预期的那样工作。@ NeilButterworth,这是一个简化的例子,我正在努力解决一个我们不能改变的供应商库。@ TyZoTo我的意思是,如果你尝试在C++代码中使用它的新名称中的这个变量,你将最终会出现链接错误,因为变量没有被定义。显然,你不喜欢在C++侧使用这个变量,只想把标题编译一下——这是你忘了提到的重要细节。是的,毫不奇怪,将名称导出改为其他东西将解决问题。但只有当原始名称从未在任何地方使用时,在这种情况下为什么不将其全部删除?不,它不起作用,因为它只影响外部声明b
ut不影响变量定义。现在,ExtExt导出变量是未定义的。@ Ant:不确定你的观点是什么,它改变了由关键字定义的变量名的名称,但实际上并不影响C++应用程序所使用的任何东西,因为它无论如何都不能使用这些名称。这允许它进行编译。任何与它动态链接的东西都会像预期的那样工作。@ NeilButterworth,这是一个简化的例子,我正在努力解决一个我们不能改变的供应商库。@ TyZoTo我的意思是,如果你尝试在C++代码中使用它的新名称中的这个变量,你将最终会出现链接错误,因为变量没有被定义。显然,你不喜欢在C++侧使用这个变量,只想编译头部——这是你忘了提到的重要细节。
#include "cheader.h"
#include <stdio.h>

int export = 0;

int printfFromC()
{
    export++;
    return printf("Hello from C (invocation %d) !\n", export);
}
------ Build started: Project: ConsoleApplication1, Configuration: Debug Win32 ------
  main.cpp
c:\[...]\cheader.h(4): warning C4091: 'extern ': ignored on left of 'int' when no variable is declared
c:\[...]\cheader.h(4): error C2143: syntax error: missing ';' before 'export'
c:\[...]\cheader.h(4): error C3378: a declaration can be exported only from a module interface unit
extern "C" {
    #include "cheader.h"
}

int main()
{
    printfFromC();
    return 0;
}
extern "C" {
    #define export extern_export
    #include "cheader.h"
    #undef export
}

int main()
{
    printfFromC();
    return 0;
}