在Visual Studio 2010中编译为C代码

时间:2014-11-17 17:25:29

标签: c++ c visual-studio-2010

我正在编写一些C代码来与一块硬件连接。此硬件具有内置API函数,这些函数在头文件中定义,包含在extern“C”块中。出于某种原因,当我在属性表中选择“编译为C代码”时,我无法编译程序。更奇怪的是,当我“编译为C ++”时,我可以得到它没有错误,不要更改任何代码,然后将其更改回“编译为C”。到底是怎么回事?我只有两个文件是main.c,header_file.h和一个definitions_file.h(在header_file.h中为#include)。

我写了一个非常简单的程序来说明发生了什么:

#include "header_file.h"

int main(){
  return 0;
}

为了提供更多细节,我得到的错误来自头文件,看起来像:

#ifdef __cplusplus
extern "C" {
#endif

#include defines_file.h

FUNC_API(int) Function(Type1 var1, Enum2 var2, Type3 var3, void* ptr=0);

#ifdef __cplusplus
}
#endif

definitions_file.h类似于:

enum Enum2{
//enumerator list
};

错误是:

1>c:\header_file\include\header_file.h(78): error C2146: syntax error : missing ')' before identifier 'var2'
1>c:\header_file\include\header_file.h(78): error C2081: 'Enum2' : name in formal parameter list illegal
1>c:\header_file\include\header_file.h(78): error C2061: syntax error : identifier 'var2'
1>c:\header_file\include\header_file.h(78): error C2059: syntax error : ';'
1>c:\header_file\include\header_file.h(78): error C2059: syntax error : ','
1>c:\header_file\include\header_file.h(78): error C2059: syntax error : ')'

似乎它认为Enum2Type1的变量名称。就好像我错过了Enum2定义,但我不是 - 它在definitions_file.h中定义。我注意到的一件事是Enum2没有在“extern C”块中定义。那是问题吗?我不想更改头文件,因为我没有写它们。 (我仍然不能100%确定“外部C”是如何工作的。)

2 个答案:

答案 0 :(得分:3)

声明为extern "C"的接口本身必须是有效的C;所以界面:

  • 可能不是班级成员
  • 可能不会超载
  • 可能不涉及班级类型
  • 可能没有可选参数
  • 必须在语法上有效,因为C代码。

你可以使用POD结构,只要它们自己被声明为extern" C"在C ++编译中。在C中,与C ++结构不同,枚举和联合标记不是它们自己的类型名称,因此必须显式限定,或者定义typedef别名。

请注意以下内容:

#if defined __cplusplus
extern "C"
{
#endif
    // Declarations must be valid C syntax
    int function() ;
#if defined __cplusplus
}
#endif

解析为:

extern "C"
{
    // Declarations must be valid C syntax
    int function() ;  
}

在C ++中,只是:

    // Declarations must be valid C syntax
    int function() ;  

在C

重要的是,当编译为C代码时,可能不包含任何特定于C ++的内容。

extern "C"是C ++语法,用于切换所有符号名称修改,这是支持重载,类成员资格和可选参数等所必需的,并且它们无效C.它强制C ++编译中的符号名称为与C编译中的相同。

答案 1 :(得分:2)

在C语言中,您需要将枚举定义为类型,或者在将其用作类型名称时使用单词enum为其添加前缀。

因此,您需要修改定义

//replace this:
enum Enum2{A,B,C,D};

//with this
typedef enum{A,B,C,D} Enum2;

或者您可以保持定义相同并将函数签名更改为

FUNC_API(int) Function(Type1 var1, enum Enum2 var2, Type3 var3, void* ptr);

事实上,C和C ++是两种截然不同的语言,如果标题没有用两种语言中的一种编写,那么你可以在不修改它的情况下使用它。

编辑:正如@Clifford所提到的,struct类型也是如此。

struct Type1  //this is passed as "struct Type1 pName"
{
    int a,b,c;
};

typedef struct //this is passed as "Type2 pName"
{
    int a,b,c;
}Type2;

//this is passed as either "struct type3 pName" or "type3_t pName"
typedef struct type3
{
    int a,b,c;
}type3_t;