Я хочу реализовать функцию с OpenGL для рендеринга цилиндра в C++. Подпись моей функции следующие:
#define POINTS_NUM 15
#define DEMESION 3
void drawCylinder( int slices, int segments, GLfloat (&vertices)[ POINTS_NUM ][ DEMESION ] );
Я хочу использовать ссылку на двухмерную антенную решетку для ограничения ввода данных пользователем, но некоторое странное поведение происходит. Когда я реализую функцию, объявленную как выше, ошибка компоновщика происходит:
Ошибка 1 ошибка LNK2005: "плавание (* ваза) [3]" (? ваза @@ 3PAY02MA) уже определенный в shapes.obj vase.obj VaseAndAnimation
Здесь vase
определяется как:
GLfloat vase[ POINTS_NUM ][ DEMESION ];
Сначала, я думал, что было что-то не так с последним размером. Таким образом, я опустил его в своей второй пробной версии. На этот раз объявление моей функции похоже на это:
void drawCylinder( int slices, int segments, GLfloat (&vertices)[ POINTS_NUM ][] );
Теперь ошибка времени компиляции происходит при вызове как (vase
определение не изменяется):
drawCylinder( 10, 10, vase );
Ошибка компиляции:
Ошибка 1 ошибка C2087: 'вершины': пропавшие без вести нижнего индекса d:\visual studio 2008\projects\project1\computer graphics\vaseandanimation\shapes.h 25 VaseAndAnimation
Ошибка 2 ошибки C2664: 'drawCylinder': не может преобразовать параметр 3 от 'GLfloat [14][3]' до 'GLfloat (и) [14] [1]' d:\Visual Studio 2008\Projects\Project1\Computer Graphics\VaseAndAnimation\vase.cpp 64 VaseAndAnimation
Ошибка 3 ошибки C2087: 'вершины': пропавшие без вести нижнего индекса d:\visual studio 2008\projects\project1\computer graphics\vaseandanimation\shapes.h 25 VaseAndAnimation
Ошибка 4 ошибки C2087: 'вершины': пропавшие без вести нижнего индекса d:\Visual Studio 2008\Projects\Project1\Computer Graphics\VaseAndAnimation\shapes.cpp 12 VaseAndAnimation
От этой ошибки я вижу тот параметр vertices
действительно рассматривается ссылка на двухмерную антенную решетку, но почему vase
проанализированный как float (* vase)[3]
в моей первой версии?
Моим IDE является Visual Studio 2008. Я не попробовал его GCC; то поведение зависимо от компилятора?
Надежда кто-то может дать мне руку для избавлений от прерывания.
Ваша первая декларация в порядке. Похоже, что вы определили vase
в заголовочном файле.
Похоже, проблема в том, что ваза
определена в файле заголовка. Вы должны только объявлять переменные в файлах заголовков.
Это вызывает проблему, потому что несколько определений создают несколько одинаковых символов, что сбивает компоновщик с толку (отсюда и ошибка компоновщика). Когда компоновщик пытается сопоставить ссылки на переменную с фактическим определением, он не знает, какое из них использовать.
Защита заголовка не защищает от этого. Макросы, используемые в защите заголовка, определены только для каждой единицы трансляции . Каждый раз, когда ваш компилятор начинает компилировать новый файл .cpp (игнорируя сборки Unity и т. Д.), Это новая единица перевода, и, по сути, компилятор начинает с нуля, не зная о каких-либо символах, которые были ранее определены.
Чтобы исправить это, только объявите ваши переменные в файлах заголовков:
// extern specifies that the definition is elsewhere.
extern int myGlobalVariable;
, а затем определите эту переменную в одном исходном файле.
int myGlobalVariable;