2011-08-12 7 views
7

Mam dużo kodu w C++, pierwotnie zbudowany na PC. Staram się, aby działał z Objective-C na Macu. W tym celu stworzyłem framework Objective-C do przechowywania kodu C++ i dodano cienkie opakowanie. Ale napotykam problem typedef w moim C++.Używanie C++ z Objective-C, Jak mogę naprawić "Conflicting declaration" typedef int BOOL ""?

Podczas pracy z C++ na komputerze użyłem zmiennej BOOL zdefiniowanej w WinDef.h. Więc kiedy przeniosłem wszystko na Maca, dodałem w typedef int BOOL;, aby upewnić się, że zmienna BOOL nadal będzie się kompilować zgodnie z oczekiwaniami.

Ale kiedy próbuję skompilować, pojawia się błąd: "Conflicting declaration 'typedef int BOOL'". Zakładam, że dzieje się tak dlatego, że BOOL jest słowem kluczowym w Objective-C i tak jest już zdefiniowane. Nie mogę też używać Objective-C BOOL, ponieważ jest to znak bez znaku, a nie int.

Podczas gdy szukałem możliwych rozwiązań znalazłem one że wspomina undefining BOOL, ale nie mogłem znaleźć jak to zrobić (ani nie wiem, czy to rzeczywiście działa). Another sugeruje zmianę nazwy BOOL BOOL na kod w pliku C++ na coś, co nie jest słowem kluczowym. Ta sugestia nie jest dla mnie opcją, ponieważ inne projekty opierają się na kodzie C++. Najlepiej, jeśli jakiekolwiek zmiany, które wprowadzam, powinny pozostać w jednym pliku lub przynajmniej nie powinny mieć negatywnego wpływu na kod na komputerze z systemem Windows.

Jak mogę nie zdefiniować definicji obiektu BOOL dla moich plików C++ i użyć definicji C++, którą dodałem? Czy istnieje lepszy sposób radzenia sobie z tym problemem?

W przypadku pomaga Używam: Xcode 3.2.5, 64-bit i Mac OS X 10.6.6

Dzięki za wszelkie wskazówki!

+0

Dlaczego używasz 'BOOL' w pierwszej kolejności? C++ ma już typ 'bool'. –

+1

Ponieważ w systemie Windows wiele interfejsów API używa typu BOOL zdefiniowanego przez system Windows, który jest rzeczywiście int. Nie jest kompatybilny z BOOL, zwłaszcza jeśli jest częścią struktury, która musi zostać przekazana do takiego API (w Windowsie bool ma rozmiar bajtowy, a BOOL ma cztery bajty). –

Odpowiedz

5

jestem trochę zdezorientowany przez niektóre dyskusji, ale zamiast typedef int BOOL; jak o tylko:

#ifndef BOOL 
    #define BOOL int 
#endif 

Jeśli używasz typedef następnie #undef nie będzie działać, ponieważ są dwie różne rzeczy. #define/#undef operuje na symbolach preprocesora, które zastępują, podczas gdy typedef jest częścią języka, który tworzy alias innego typu.

Symbol preprocesora może być w dowolnym momencie niezdefiniowany, ponieważ jest po prostu instrukcją do preprocesora, która mówi mu, aby nie używała tej definicji podczas wykonywania zamienników. Jednak nie można nieokreślać wartości typedef, ponieważ jest ona tworzona w ramach określonego zakresu, a nie przetwarzania liniowego, które odbywa się za pomocą preprocesora. (W ten sam sposób, nie spodziewałbyś się, że będziesz w stanie zadeklarować zmienną globalną int x;, a następnie w pewnym momencie twojego kodu będzie mógł powiedzieć "przestań rozpoznawać x jako zmienną.')

Powodem, dla którego sugeruję # definicję w mojej odpowiedzi jest to, że możliwe jest, że ObjectiveC #define jest uderzany tylko podczas kompilowania niektórych z twojego kodu. To może być wyjaśnienie, dlaczego możesz dostać błędy w C++ po usunięciu typedef, ale nadal pojawia się konflikt, jeśli jest. Ale jeśli więc założenia są poprawne, po sprawdzeniu definicji przed próbą aby go zdefiniować, powinieneś być w stanie uniknąć sprzecznych definicji, gdy się pojawią.

Uwaga końcowa: w tej konkretnej sytuacji możesz po prostu wstawić do czeku swoją typedef zamiast #define. Jednakże, skierowaliśmy się na to, tak jak ja to robiłem, ponieważ jest to bardzo popularny idiom, a ponieważ ten blok uniemożliwiłby Ci dwukrotne zdefiniowanie go w swoim kodzie C++, jeśli kończy się on dwukrotnie. Prawdopodobnie nie są to bardzo ważne powody, jeśli bardzo wolisz typedef i wiesz, że to nie problem w kodzie. :)

+0

:) Ups, dobrze, pisałem po tym, jak twój problem został już rozwiązany, cieszę się, że to działa! – shelleybutterfly

+0

Próbowałem obu sposobów, o których wspomniałeś ('# ifdef' z' #define BOOL int' i 'typedef int BOOL;' inside). Pierwszy sposób działał dobrze, ale drugi wygenerował taki sam błąd "Sprzeczna deklaracja" (zupełnie nie rozumiem, jak to możliwe, po prostu powtarzam to, co mi powiedział Xcode!). Dzięki za alternatywne rozwiązanie! –

+0

huh, to bardzo dziwne. no cóż, prawdopodobnie jedna z tych rzeczy, w których najlepiej nie myśleć zbyt mocno. : D i dzięki za notatkę! ♡ – shelleybutterfly

0

AFAIK, BOOL to także #define w Objective-C. Będziesz mieć problemy z konflikcie BOOL zdefiniowania, nawet jeśli uda się

#undef BOOL 

ponieważ typ i jego typ nie muszą dopasować się wielkością i „signedness”. Czy Twój BOOL naprawdę musi być int, zamiast cokolwiek to jest, co Obj-C definiuje jako? Innymi słowy, czy nie możesz ominąć swojego #define i po prostu użyć tego Obj-C?

+0

Jeśli skomentuję mój "typedef int BOOL" w moim pliku C++, otrzymuję błędy w całej reszcie moich plików C++, gdy tylko użyty zostanie 'BOOL'. Nie sądzę, żebym mógł użyć definicji BOJ Obj-C. –

+0

Jak to możliwe? Mam nadzieję, że zostanie to zdefiniowane tylko raz. Po prostu usuń to i dodaj "objc.h". FWIW, jakie błędy? –

+1

Och, myślę, że zadziałało! Przynajmniej teraz kompiluje bez błędów. Zrobiłem to, co powiedziałeś, i dodałem w # #include ", więc mam nadzieję, że sprawy będą tu dławić. Dziękuję Ci! FWIW były to głównie błędy typu '' BOOL 'nie określa typu i 'ISO C++ zabrania deklarowania' BOOL 'bez typu". –

0

Gdybyś mógł cofnąć się w czasie, powiedziałbym "Nie używaj typedef int BOOL w swoim własnym kodzie".

Teraz, gdy już to zrobiliście, jesteście trochę podekscytowani. Generalnie powinieneś unikać używania zewnętrznych typów danych do własnego kodu, z wyjątkiem interfejsu z kodem zewnętrznym. Typy standardowe są w porządku, zakładając, że możesz zagwarantować kompilację za pomocą standardowego kompilatora zgodnego z każdą platformą, na którą celujesz.

Najbardziej przyszłościowym rozwiązaniem jest zaprzestanie używania BOOL jako typu w kodzie agnostycznym platformy. W międzyczasie możesz użyć różnego rodzaju hakerów preprocesora, aby użyć kompilacji BOOL, ale możesz natknąć się na dziwne błędy łącza, jeśli nie używasz wszędzie BOOL w ten sam sposób (przez #includes).

0

używam cmake załadować freeimage biblioteki i używam Kubuntu 14.x miałem ten problem z

"error: conflicting declaration ‘typedef CARD8 BOOL’" 

i pomyślałem, że byłoby dobrze, aby podzielić się moją rozwiązanie z osobami, które mają ten problem!

zainstalować FreeImage w systemie Linux:

sudo apt-get install libfreeimage-dev 

w moim pliku CMakeLists.txt mam:

set(FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY /usr/libs) 
find_path(FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY, FreeImage.h) 
find_library(FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY, freeimage) 
include_directories(${FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY}) 
target_link_libraries(freeimage) 

I w moim main.cpp mam:

#include <FreeImage.h> 
#ifndef CARD8 
#define BYTE CARD8 
#define BOOL CARD8 
#endif 

a niektóre dodatkowy kod do przechwytywania ramki OpenGl na dysku:

void generateImage(){ 
    int w, h; // get the width and height of the OpenGL window! 
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
    GLubyte * pixels = new GLubyte[3*w*h]; 
    glReadPixels(0,0,w,h,GL_RGB,GL_UNSIGNED_BYTE, pixels); 

    FIBITMAP * image = FreeImage_ConvertFromRawBits(pixels,w,h,3 * w, 24, 0x0000FF, 0xFF0000, 0x00FF00, false); 
    FreeImage_Save(FIF_BMP,image, "../img/text.bmp",0); 

    //Free resource 
    FreeImage_Unload(image); 
    delete[] pixels; 
} 

Mam nadzieję, że pomoże to tym, którzy mają z tym problem!

Pozdrowienia Kahin