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

У меня много кода на 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-bit и Mac OS X 10.6.6

Спасибо за любые советы!

Ответы [ 4 ]

6 голосов
/ 13 августа 2011

Меня немного смущают некоторые обсуждения, но вместо 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 и знаете, что это не проблема в коде.:)

0 голосов
/ 20 февраля 2015

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

"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)

И в моем main.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;
}

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

С уважением, Кахин

0 голосов
/ 15 августа 2011

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

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

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

0 голосов
/ 13 августа 2011

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

#undef BOOL

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

...