我想用OpenGL实现一个函数来用C ++渲染一个圆柱体。我的功能签名如下:
#define POINTS_NUM 15
#define DEMESION 3
void drawCylinder( int slices, int segments, GLfloat (&vertices)[ POINTS_NUM ][ DEMESION ] );
我想使用对二维数组的引用来限制用户输入,但是发生了一些奇怪的行为。当我实现上面声明的函数时,会发生链接器错误:
错误1错误LNK2005:“float(* vase)[3]”(?vase @@ 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:'vertices':缺少下标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:'vertices':缺少下标d:\ visual studio 2008 \ projects \ project1 \ computer graphics \ vaseandanimation \ shapes.h 25 VaseAndAnimation
错误4错误C2087:'vertices':缺少下标d:\ Visual Studio 2008 \ Projects \ Project1 \ Computer Graphics \ VaseAndAnimation \ shapes.cpp 12 VaseAndAnimation
从这个错误中,我可以看到参数vertices
实际上被视为对二维数组的引用,但为什么vase
在我的第一个版本中被解析为float (* vase)[3]
? / p>
我的IDE是Visual Studio 2008.我没有尝试过GCC;该行为依赖于编译器吗?
希望有人可以帮我摆脱陷阱。
答案 0 :(得分:2)
你的第一份声明没问题。似乎您已在头文件中定义了vase
。
答案 1 :(得分:1)
看起来问题只是vase
在头文件中定义。您只应在头文件中声明变量。
这会导致问题,因为多个定义产生多个相同的符号,这会混淆链接器(因此链接器错误)。当链接器尝试将对变量的引用与实际定义匹配时,它不知道要使用哪一个。
头部警卫不能防止这种情况发生。标头保护中使用的宏仅定义为每个转换单元。每次你的编译器开始编译一个新的.cpp文件(忽略统一构建等)时,这是一个新的翻译单元,基本上编译器从头开始,不知道任何先前已定义的符号。
要解决此问题,只有在头文件中声明您的变量:
// extern specifies that the definition is elsewhere.
extern int myGlobalVariable;
然后在一个源文件中定义该变量。
int myGlobalVariable;