Как объявить непрозрачную анонимную структуру, определенную сторонней организацией?

Я работаю над оболочкой стороннего модуля. Я надеюсь, что в моем основном заголовочном файле нет сторонних заголовочных файлов. Каждый тип параметра и тип возвращаемого значения непрозрачны, если их только объявить. Но есть анонимная структура, определенная следующим образом:

typedef struct {
    int x;
    int y;
    int width;
    int height;
} IppiPoint;

Я не могу изменить сторонний заголовочный файл. Я понятия не имею, чтобы заявить об этом. Вот что я пробовал и сообщения об ошибках, которые я получил

1.

struct IppiPoint;
error C2371: 'IppiPoint' : redefinition; different basic types

2.

typedef struct IppiPoint;
... warning C4091: 'typedef ' : ignored on left of 'IppiPoint' when no variable is declared
... error C2371: 'IppiPoint' : redefinition; different basic types

Как объявить такую ​​анонимную структуру?


person Chen OT    schedule 30.03.2016    source источник
comment
Почему вы хотите объявить структуру? Вы явно не должны этого делать, используйте только псевдоним типа, уже предоставленный вашим заголовочным файлом третьей части.   -  person Some programmer dude    schedule 30.03.2016
comment
Я хочу переместить псевдоним типа в файл cpp, тогда мой клиент не увидит никаких сторонних заголовков при использовании.   -  person Chen OT    schedule 30.03.2016
comment
А как насчет IppiPoint;?   -  person Fynn    schedule 30.03.2016
comment
@Fynn Вы имеете в виду объявить это без структуры? Это заставляет компилятор жаловаться на отсутствие спецификатора типа.   -  person Chen OT    schedule 30.03.2016
comment
Ну, в настоящее время ваш источник do видит заголовочный файл третьей части (иначе вы не получили бы ошибку переопределения). И если вы объявляете переменные этого типа, не являющиеся указателями, или пытаетесь выделить их с помощью malloc, то вам в любом случае нужна полная структура.   -  person Some programmer dude    schedule 30.03.2016
comment
Вы не можете предварительно объявить анонимную структуру. Анонимная структура — ужасная форма экономии нажатий клавиш. Вам нужно либо изменить заголовок, либо обернуть структуру собственным типом.   -  person molbdnilo    schedule 30.03.2016
comment
@JoachimPileborg На самом деле я не хочу, чтобы мой клиент напрямую использовал ippiPoint. У меня есть пользовательская структура MyPoint в качестве среднего уровня. Но я хочу MyPoint удобнее, я поставил operator ippiPoint () const;. И это единственное место, где можно увидеть ippiPoint. Поэтому я ищу возможные способы только объявить его и скрыть определение реальной структуры в файле cpp.   -  person Chen OT    schedule 30.03.2016
comment
Итак, у вас есть оператор преобразования, который преобразует экземпляр MyPoint в тип IppiPoint? И потом вы говорите, что это единственное использование типа IppiPoint? Это не имеет смысла, вы создаете оператор преобразования, который не собираетесь использовать? Если и когда и где вы используете оператор преобразования, вы также используете тип и вам нужна полная структура, нет никакого способа обойти это.   -  person Some programmer dude    schedule 30.03.2016
comment
Я думаю, что все клиенты используют MyPoint в качестве параметра для моих функций (включая заголовок). И я также использую MyPoint в cpp для передачи (неявного преобразования) IppiPoint в функцию imp. Да, ты прав. Возможно, было бы неправильно помещать все эти вещи в MyPoint. Если я хочу скрыть все детали, я должен определить такую ​​функцию преобразования и в cpp. Спасибо   -  person Chen OT    schedule 30.03.2016


Ответы (1)


Создайте свой собственный тип struct Bob;. Используйте его вместо этого.

В cpp определите struct Bob следующим образом:

struct Bob {
  IppiPoint contents;
};

и пока IppiPoint имеет стандартный макет, вы можете reinterpret_cast<IppiPoint*>(pointer_to_bob) легально.

Указатель на объект типа структуры стандартного макета может быть reinterpret_cast для указания на его первый нестатический элемент данных (если он имеет нестатические элементы данных) или в противном случае его первый подобъект базового класса (если он есть) и наоборот. наоборот (заполнение перед первым элементом данных не допускается). Обратите внимание, что к результату такого приведения по-прежнему применяются строгие правила псевдонимов.

Может быть, выбрать лучшее имя, чем Bob.

person Yakk - Adam Nevraumont    schedule 30.03.2016
comment
Разве это reinterpret_cast не нарушит строгое правило псевдонимов? - person TartanLlama; 30.03.2016
comment
@TartanLlama Сделайте struct Bob { IppiPoint contents; }, тогда переинтерпретация гарантированно сработает. - person Yakk - Adam Nevraumont; 30.03.2016