Компилировать как код C в Visual Studio 2010

0

Я пишу код C для взаимодействия с частью оборудования. Это аппаратное обеспечение имеет встроенные функции API, которые определены в файле заголовка, заключенном в блок extern "C". По какой-то причине я не могу заставить программу компилироваться, когда я выбираю "компилировать как код С" в листах свойств. Даже незнакомец, я могу заставить его не давать ошибок, когда я "компилирую как C++", не меняю никакого кода, а затем меняю его на "компилировать как C". Что происходит? Единственными двумя файлами, которые у меня есть, являются main.c, header_file.h и define_file.h (который является #include d в header_file.h).

Я написал очень простую программу, чтобы проиллюстрировать, что происходит:

#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

Файл define_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, но я не - он определен в define_file.h. Одна вещь, которую я заметил, это то, что Enum2 не определен внутри блока "extern C". Это проблема? Я не хочу менять файлы заголовков, потому что я их не писал. (Я все еще не уверен на 100%, как работает "extern C").

  • 0
    extern "C" не является допустимым C, это конструкция C ++. Если вы компилируете код как C, то вам нужен extern (или вообще нет спецификатора хранилища, так как функции по умолчанию являются extern ).
  • 0
    Хорошо, в таком случае, как я могу использовать функции API в моем C-коде? Я не могу изменить формат #ifdef __cplusplus / "extern C" - это не мой код.
Показать ещё 6 комментариев
Теги:
visual-studio-2010

2 ответа

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++ - это два разных языка, и если заголовок не был написан с одним из двух, то вы можете просто не использовать его, не изменяя его.

edit: как упоминалось в @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;
  • 0
    @AmberWild, что кажется неправильным, так как вы можете видеть, как они оба независимо работают в C99: ideone.com/Jb4wYW (возможно, это идиосинкразия VS)
  • 1
    @AmberWilds: Если вам приходилось делать то и другое, значит, у вас все еще что-то не так. Аналогично, Type1 должен быть псевдонимом typedef, а не классом или прямой структурой.
Показать ещё 3 комментария
3

Объявленный интерфейс extern "C" должен быть действительно C; поэтому интерфейс:

  • Не может быть членом класса
  • Не может быть перегружен
  • Может не включать типы классов
  • Может не иметь необязательных аргументов
  • Должен быть синтаксически корректным как код C.

Вы можете использовать структуры POD, пока они сами объявляются extern "C" в компиляции C++. В C, в отличие от C++ struct, теги enum и union не имеют собственных имен типов, поэтому они должны быть явно квалифицированы или заданы псевдоним 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.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню