Используя C++ с Objective-C, как я могу исправить "конфликтующее объявление 'typedef int BOOL'"?

у меня много кода на C++, первоначально построенный на ПК. Я пытаюсь заставить его работать с Objective-C на Mac. С этой целью я создал фреймворк Objective-C для размещения кода C++ и добавил тонкую оболочку. Но я столкнулся с проблемой typedef в моем коде C++.

когда я работал с C++ на ПК, я использовал BOOL переменная, определенная в WinDef.h. Поэтому, когда я переместил все на Mac, я добавил в typedef int BOOL; чтобы убедиться, что BOOL переменная все равно будет компилироваться как ожидаемый.

но когда я пытаюсь скомпилировать, я получаю ошибку:"Conflicting declaration 'typedef int BOOL'". Я предполагаю, что это потому, что BOOL является ключевым словом в Objective-C, и поэтому уже определено. Я также не могу просто использовать Objective-C BOOL поскольку это беззнаковый символ, а не int.

пока я искал возможные решения я нашел один что упоминает удаления определений типа bool, но я не мог найти, как это сделать (и я не знаю, действительно ли это работает). еще один предполагает переименование BOOL в файлах C++ к чему-то, что не является ключевым словом. Это предложение не является вариантом для меня, потому что другие проекты полагаются на код c++. В идеале любые изменения, которые я делаю, должны оставаться в одном файле или, по крайней мере, не должны негативно влиять на код на машине Windows.

как я могу определить определение Objective-C BOOL для моих файлов c++ и использовать определение c++, которое я добавил? Есть ли лучший способ справиться с этим проблема?

если это поможет, я использую: Xcode 3.2.5, 64-бит и Mac OS X 10.6.6

Спасибо за любые рекомендации!

4 ответов


Я немного смущен некоторыми из обсуждений, но вместо typedef int BOOL; Как насчет просто:

#ifndef BOOL
  #define BOOL int
#endif

если вы используете typedef затем #undef не сработает, так как это две разные вещи. #define/#undef работают с символами препроцессора, которые выполняют замены, тогда как typedef является частью языка, который создает псевдоним другого типа.

символ препроцессора может быть определено в любой момент, потому что это просто инструкция к препроцессор, который говорит ему больше не использовать это определение при выполнении замен. Однако,typedef не может быть неопределенным, так как это то, что создается в определенной области, а не линейная обработка, которая происходит с помощью препроцессора. (Точно так же вы не ожидаете, что сможете объявить глобальную переменную int x; а затем в какой-то момент в вашем коде можно сказать: "прекратите распознавать x как переменную.')

причина, по которой я предлагаю #define в моем ответ заключается в том, что возможно, что ObjectiveC #define попадает только при компиляции некоторого кода. Это может быть объяснением того, почему вы можете получить ошибки в своем C++ при удалении typedef, но все равно получите конфликт,если он есть. Но, таким образом, если предположения верны, как только вы проверите определение до попытки определить его, вы сможете избежать конфликтующих определений, когда они происходят.

в качестве заключительного примечания: в этой конкретной ситуации вы также можно просто положить ваш typedef внутри чека вместо #define. Тем не менее, я тяготел к тому, чтобы сделать это так, как я сделал, потому что это очень распространенная идиома, и потому, что этот блок также помешает вам определить его дважды в вашем коде C++, если он будет включен дважды. Вероятно, ни одна из очень убедительных причин, если вы очень предпочитаете typedef и знаю, что это не проблема в коде. :)


насколько я знаю, BOOL это #define в Objective-C тоже. У вас будут проблемы с конфликтом BOOL определить, даже если вам удастся

#undef BOOL

потому что ваш тип и его тип не обязательно совпадают по размеру и"значению". Должен ваш BOOL действительно быть int, вместо того, что Obj-C определяет его как? Другими словами, вы не можете опустить свой #define и просто использовать Obj-C?


если бы вы могли вернуться в прошлое, я бы сказал "Не используйте typedef int BOOL в своем коде".

теперь, когда вы на самом деле сделали это, хотя, вы находитесь в некотором рассоле. Как правило, следует избегать использования внешних типов данных для собственного кода, кроме как для взаимодействия с внешним кодом. Стандартные типы прекрасны, предполагая, что вы можете гарантировать компиляцию со стандартным совместимым компилятором на каждой целевой платформе.

самое дальновидное решение-прекратить использование BOOL как тип в вашем агностик код платформы. В то же время, вы можете использовать все виды хакерства препроцессора, чтобы использовать BOOL compile, но вы можете столкнуться с некоторыми странными ошибками ссылок, если не используете BOOL таким же образом (через #includes) везде.


я использую cmake для загрузки библиотеки freeimage, и я использую kubuntu 14.икс У меня была эта проблема с

"error: conflicting declaration ‘typedef CARD8 BOOL’" 

и я подумал, что было бы хорошо поделиться своим решением с людьми, у которых есть эта проблема!

установить FreeImage на Linux:

sudo apt-get install libfreeimage-dev

в моих CMakeLists.txt файл у меня есть:

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)

и в моем основном.cpp у меня:

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

и дополнительный код для захвата фрейма OpenGl на диске:

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;
}

Я надеюсь это помогает тем, у кого с этим проблемы!

С уважением Кахин!--6-->