简体   繁体   English

在Visual Studio 2010中作为C代码编译

[英]Compile as C code in Visual Studio 2010

I am writing some C code to interface with a piece of hardware. 我正在编写一些C代码以与硬件连接。 This hardware has built-in API functions, which are defined in a header file, enclosed in an extern "C" block. 该硬件具有内置的API函数,这些函数在头文件中定义,并包含在外部“ C”块中。 For some reason, I cannot get the program to compile when I select "compile as C code" in the property sheets. 由于某些原因,当我在属性表中选择“编译为C代码”时,无法使程序编译。 Even stranger, I can get it to give no errors when I "compile as C++", don't change any code, then change it back to "compile as C". 甚至更陌生,当我“作为C ++编译”时,我也不会得到任何错误,不更改任何代码,然后将其更改回“作为C编译”。 What is going on? 到底是怎么回事? The only two files I have are main.c, header_file.h, and a defines_file.h (which is #include d in header_file.h). 我仅有的两个文件是main.c,header_file.h和define_file.h(在header_file.h中为#include d)。

I wrote a very simple program to illustrate what is happening: 我编写了一个非常简单的程序来说明正在发生的事情:

#include "header_file.h"

int main(){
  return 0;
}

To give some more detail, the error I am getting is coming from the header file, which looks something like: 为了提供更多细节,我得到的错误来自头文件,它看起来像:

#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

The defines_file.h looks like: define_file.h看起来像:

enum Enum2{
//enumerator list
};

The errors are: 错误是:

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 : ')'

It seems like it's thinking that Enum2 is a variable name of Type1 . 似乎在考虑Enum2Type1的变量名。 It's as though I'm missing the Enum2 definition, but I'm not - it's defined in defines_file.h. 好像我缺少Enum2定义,但我没有-它在define_file.h中定义。 One thing I did notice is that Enum2 is not defined inside an "extern C" block. 我注意到的一件事是Enum2没有在“ extern C”块内定义。 Is that a problem? 那是问题吗? I don't want to change the header files because I didn't write them. 我不想更改头文件,因为我没有写它们。 (I'm still not 100% sure how "extern C" works.) (我仍不确定100%“外部C”如何工作。)

The interface declared extern "C" must itself be valid C; 声明为extern "C"的接口本身必须是有效的C; so the interface: 所以界面:

  • May not be a class member 可能不是班级成员
  • May not be overloaded 可能不会超载
  • May not involve class types 可能不涉及课程类型
  • May not have optional arguments 可能没有可选参数
  • Must be syntactically valid as C code. 在语法上必须作为C代码有效。

You can use POD structs so long as they themselves are declared extern "C" in C++ compilation. 只要POD结构本身在C ++编译中声明为extern“ C”,就可以使用。 In C, unlike C++ struct, enum and union tags are not on their own type names, so must be explicitly qualified, or a typedef alias defined. 在C语言中,与C ++ struct不同,枚举和联合标记不是位于自己的类型名称上,因此必须进行显式限定,或者定义为typedef别名。

Note that the following: 请注意以下几点:

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

Resolves to: 解析为:

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

in C++, and just: 在C ++中,只是:

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

in C 在C

The important point is that when compiled as C code, nothing C++ specific may be included. 重要的一点是,当编译为C代码时,不得包含C ++专有的内容。

The extern "C" is C++ syntax to switch of all symbol name mangling that is necessary to support overloading, class membership, and optional parameters etc. and which is not valid C. It forces the symbol name in C++ compilation to be the same as that in C compilation. extern "C"是C ++语法,用于切换支持重载,类成员关系和可选参数等所必需的所有符号名改写,并且无效C。它强制C ++编译中的符号名与在C编译中。

In C you need to define an enum as a type or actually prefix it with the word enum when you use it like a type name. 在C语言中,您需要将枚举定义为类型,或者在像类型名称一样使用时,在其前面加上单词enum

So either you need to modify the definition 因此,您需要修改定义

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

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

or you can keep the definition the same and change the function signature to 或者您可以保持定义相同,然后将函数签名更改为

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

The fact of the matter is that C and C++ are two distinct languages and if the header wasn't written with one of the two in mind, then you can just not use it without modifying it. 事实是C和C ++是两种截然不同的语言,如果标头不是在编写时考虑这两种语言中的一种,那么就不能在不进行修改的情况下使用它。

edit : as @Clifford mentioned, the same goes for struct types. 编辑 :正如@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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM