我正在编写一些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 : ')'
似乎它认为Enum2
是Type1
的变量名称。就好像我错过了Enum2
定义,但我不是 - 它在definitions_file.h中定义。我注意到的一件事是Enum2
没有在“extern C”块中定义。那是问题吗?我不想更改头文件,因为我没有写它们。 (我仍然不能100%确定“外部C”是如何工作的。)
答案 0 :(得分:3)
声明为extern "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;