Несовместимость компиляции C vs C++ - не называет тип
Я пытаюсь использовать библиотеку поставщика в сочетании с моим приложением C++. Библиотека в основном основана на C, что обычно не является проблемой с extern "C" вариант, но я столкнулся с проблемой, которую компилятор C++ не принимает.
я упростил свой код в следующие файлы примеров. заголовок.h представляет заголовок из библиотеки Supper, main.c / cpp - это мои собственные файлы. Мое реальное приложение-это приложение на C++, поэтому я хочу, чтобы оно работало с main.СРР.
заголовок.ч (обратите внимание на строку u64 u64;):
#ifndef HEADER_H
#define HEADER_H
#include <stdint.h>
typedef uint64_t u64;
union teststruct {
u64 u64;
struct {
u64 x:32;
u64 y:32;
} s;
};
#endif
главная.c:
#include <stdio.h>
#include "header.h"
int main() {
union teststruct a;
a.u64=5;
printf("%xn", a.u64);
return 0;
}
главная.СРР (аналогично главной.c но с дополнительным extern "C" заявления):
#include <stdio.h>
extern "C" {
#include "header.h"
}
int main() {
union teststruct a;
a.u64=5;
printf("%xn", a.u64);
return 0;
}
компиляция main.c помощью строки
gcc -o test main.c
компилируется без проблем. Однако компиляция версии C++ с помощью компилятора g++ с командой
g++ -o test main.cpp
выдает следующие ошибки компилятора:
In file included from main.cpp:12:0:
header.h:11:9: error: ‘u64’ does not name a type
u64 x:32;
^
header.h:12:9: error: ‘u64’ does not name a type
u64 y:32;
^
проблема в том, что поставщик используется одно и то же имя (u64) как для типа, так и для имени переменной, что кажется плохой идеей, но gcc, по-видимому, принимает его. Я не хочу менять библиотеку (т. е. заголовок.з) так как он очень большой,это происходит много в коде, и я иногда получаю обновления для него. Есть ли способ заставить g++ принять эту комбинацию или способ изменить main.cpp, чтобы сделать его компилировать без изменение заголовка.ч?
3 ответов:
teststructопределяет область в C++. Вы можете сформировать квалифицированный идентификаторteststruct::u64. Таким образом, правила языка для поиска имен учитывают это, позволяя членам классов и союзов скрывать идентификаторы во внешней области. Один разu64 u64;вводится, безусловногоu64не может ссылаться на глобальный::u64, только член. И член не является типом.В C
union teststructне определяет объем. Поле может использоваться только в доступе к члену, поэтому никогда не может возникнуть конфликт. По существу поле не должно скрывать идентификатор типа области действия файла.насколько я могу судить, вы ничего не можете сделать, чтобы легко обойти это. Эта библиотека (которая является совершенно допустимой библиотекой C), не является допустимой библиотекой C++. Не отличается от того, если бы он использовал
newилиtryв качестве имен переменных. Его нужно адаптировать.
кажется, что у вас есть файл заголовка, который является незаконным в C++, поэтому вы не можете
#includeЭто в коде, скомпилированном как C++. Если вы не можете изменить файл заголовка библиотеки (например, пожаловавшись поставщику библиотеки), то самый простой вариант-написать тонкую c++-совместимую оболочку вокруг библиотеки:чтобы изолировать код C++ от заголовка C, создайте
Wrapper.hиWrapper.c, где.hдействительно для включения в C++, делает не включитьheader.h, и предоставляет все типы и функции, необходимые для взаимодействия с библиотекой. Затем, в.cвы можете#include "header.h"и реализовать все звонки (и все, что вам нужно сделать, чтобы безопасно конвертировать между типами). Это, очевидно, должно быть скомпилировано как C, а не C++.
если ваша упомянутая несовместимость между C и C++ является единственной, вы должны иметь возможность конвертировать
header.hчтобы c++ совместимый файл заголовка программно, назовите его что-то вродеheader.hpp. И тогда вы можете конвертировать новые версии таким же образом.ошибки компилятора расскажут вам все о том, что и где следует изменить:
header.h:11:9: error: ‘u64’ does not name a type
- открыть
header.h;- искать позицию 11:9;
- вставить
::там;- повторите для всех
does not name a typeошибка.обработка строк и готово.
PS: конвертеры C в C++ тоже могут это сделать.
Comments