2012-09-21 11 views
5

Witam Kompiluję program ffmpeg przy użyciu xcode, który, jak sądzę, używa języka do kompilacji. W ffmpeg znajduje się struktura ze zmienną składową o nazwie "klasa". Uważam, że jest to całkiem w porządku w C, ale clang próbuje sparsować ją jako słowo kluczowe. Każdy pomysł, jak to naprawić? Zasadniczo następujące w pliku cpp spowoduje błąd:Clang C Compiler 'class' keyword reserved?

extern C { 
    typedef struct { 
     int class; 
    } SomeStruct; 
} 

Próbuje interpretować klasy jako słowo kluczowe.

Do zobaczenia pliku, który rzuca błąd w ffmpeg to libavcodec/mpegvideo.h i muszę to uwzględnić, aby uzyskać dostęp do struktury MpegEncContext w celu wyciągnięcia informacji o ruchu.

EDIT

Powyższy przykładowy kod był tylko wykazać błąd. Ale być może można to naprawić w inny sposób. W moim rzeczywistym kodzie mam to tak:

#ifdef __cplusplus 
extern "C" { 
#endif 

    #include "libavcodec/mpegvideo.h" 
    #include "libavformat/avformat.h" 

#if __cplusplus 
} //Extern C 
#endif 

Jak to zrobić, aby uwzględnić dwa pliki jako pliki C, a nie C++?

Dzięki

+0

A twój Xcode- (ffmpeg) związanych pytanie brzmi: –

+3

hehe: 'extern COBOL {ADD A do punktu B DAJE C}' – pmg

+0

Moje Xcode ffmpeg podobne pytanie, w jaki sposób to, że nagłówek w C++ plik i go skompilować w Xcode? – user1689196

Odpowiedz

4

Jest całkowicie w porządku w C. Kiedy budujesz to jako C++, napotykasz błąd, ponieważ class jest słowem kluczowym C++.

Jeśli chodzi o jego instalację, zwykle wybiera się identyfikator inny niż class. Jednak deweloperzy ffmpeg mogą nie zgadzać się z tą zmianą. W związku z tym konieczne może być albo:

  • ograniczyć widoczność tego nagłówka do tłumaczenia C
  • lub edytować swoją własną kopię w celu wykorzystania go w C++ tłumaczenia

Na szczęście, są również przy użyciu kompilatora C, który ma dobre wsparcie dla funkcji C99 w tym przypadku. Kompilatory C, które nie obsługują dobrze C99, są szczególnie kłopotliwe dla źródeł ffmpeg (ponieważ wtedy skompilowałbyś cały program jako C++ dla funkcji C99, a liczba konfliktów byłaby znacznie wyższa).

(istnieją inne brudne sztuczki mógłby zrobić, aby spróbować obejść ten problem, ale ja ich nie wspominając)

+0

Czy możesz wyjaśnić nieco więcej, w jaki sposób mogę ograniczyć widoczność tych nagłówków do tłumaczeń C? Przypuszczam, że mógłbym przenieść dowolny kod, który używa tego pliku do pliku .c. Ale w pewnym momencie nadal będę musiał uwzględnić ten plik .c z pliku C++. – user1689196

+0

Domyślam się, że mogłem zmienić nazwę zmiennej klasowej na coś innego, ponieważ używa ona tylko pliku nagłówkowego jako odniesienia (ffmpeg jest już skompilowany do biblioteki), ale ja po prostu nie lubię bawić się plikami źródłowymi, jeśli nie muszę, sprawia, że ​​aktualizacja jest nieco trudniejsza. – user1689196

+1

@ user1689196 sure. jesteś na dobrej drodze; potrzebujesz utworzyć cienką warstwę wrappera (w C), którą możesz następnie wywołać z C++ w celu interakcji z 'SomeStruct' lub po prostu uporać się z tym aspektem programu, który zawiera' SomeStruct' wyłącznie w większej implementacji C. – justin

4

Basically the following in a cpp file will cause the error

pliki .cpp są przetwarzane jako pliki C++, a nie C i class to słowo zarezerwowane w C++.

+0

, ale czy nie powinien wymyślić C zmusić go do użycia kompilatora C? – user1689196

+5

@ user1689196, absolutnie nie. To po prostu zmieni powiązanie symboli, aby zatrzymać wymazywanie nazw. Możesz wymusić język za pomocą opcji -x. –

+0

Nie, 'extern C' zmienia tylko sposób, w jaki działa mangling nazw. Aby skompilować jako C, użyj .c – Joe

1

Jeśli nie masz wyboru, aby zmienić nazwę niczego w tych plikach nagłówkowych, można po prostu zastąpić class tokena przez coś innego

#ifdef __cplusplus 
extern "C" { 
# define class videoClass 
#endif 

    #include "libavcodec/mpegvideo.h" 
    #include "libavformat/avformat.h" 

#if __cplusplus 
# undef class 
} //Extern C 
#endif 

jest to dość brudny hack, ale dla takiego kodu źle sprzężonym nie masz wielkiego wyboru. Prawdziwym rozwiązaniem byłoby posiadanie w tych plikach wszystkich członków struct używających nazw, które mają jakiś rodzaj prefiksu lub tak, jak to się dzieje w warstwie sieci. Tam wszyscy członkowie mają pewne prefiksy jako ss_ lub sa_ i takie problemy są bardzo mało prawdopodobne.

+0

to jest główna, brudna sztuczka, którą miałem na myśli, gdy pisałem o brudnych sztuczkach w mojej odpowiedzi :) * (nie martw się, nie odrzucę, ponieważ faktycznie zadałeś sobie trud wskazania i wyjaśnienie problemu i wyjaśnienie, że jest brudny) * – justin