2010-06-24 141 views
5

我想用OpenGL实现一个函数来渲染C++中的圆柱体。我的功能的签名如下:参考二维阵列

#define POINTS_NUM 15 
#define DEMESION 3 

void drawCylinder(int slices, int segments, GLfloat (&vertices)[ POINTS_NUM ][ DEMESION ]); 

我想使用对二维数组的引用来限制用户输入,但一些奇怪的行为正在发生。当我实现如上声明的函数时,链接器错误:

Error 1 error LNK2005: "float (* vase)[3]" ([email protected]@3PAY02MA) already defined in 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); 

编译错误:

Error 1 error C2087: 'vertices' : missing subscript d:\visual studio 2008\projects\project1\computer graphics\vaseandanimation\shapes.h 25 VaseAndAnimation

Error 2 error C2664: 'drawCylinder' : cannot convert parameter 3 from 'GLfloat [14][3]' to 'GLfloat (&)[14][1]' d:\Visual Studio 2008\Projects\Project1\Computer Graphics\VaseAndAnimation\vase.cpp 64 VaseAndAnimation

Error 3 error C2087: 'vertices' : missing subscript d:\visual studio 2008\projects\project1\computer graphics\vaseandanimation\shapes.h 25 VaseAndAnimation

Error 4 error C2087: 'vertices' : missing subscript d:\Visual Studio 2008\Projects\Project1\Computer Graphics\VaseAndAnimation\shapes.cpp 12 VaseAndAnimation

从这个错误,我可以看到参数vertices真的被视为一个二维数组的参考,但为什么vase解析为float (* vase)[3]在我的第一个版本?

我的IDE是Visual Studio 2008.我还没有尝试过使用GCC;那是行为编译器依赖的?

希望有人能帮我摆脱陷阱。

+0

可能的重复[如何将对二维数组的引用传递给函数?](http://stackoverflow.com/questions/404232/how-do-i-pass-a-参考到二维阵列到函数) – 2010-06-24 04:37:01

回答

2

您的第一个声明很好。似乎你已经在头文件中定义了vase

+0

是的,你是对的。仔细检查我的代码后,我发现该花瓶是在函数声明之前定义的。但为什么我不能在头文件中定义数组?我对此没有任何限制。谢谢。 – 2010-06-24 04:49:54

+0

您的标题包含在几个cpp文件中。这意味着“花瓶”将被定义多次。你可以在头文件中声明它,然后在一个cpp文件中定义它。 – 2010-06-24 04:58:59

+0

是的,我知道这种情况。但是,我定义了一个宏以避免重复。仍然存在这个问题。 – 2010-06-24 05:06:34

1

它看起来像问题是vase在头文件中定义。您应该只在头文件中使用声明变量。

这会导致一个问题,因为多个定义会生成多个相同的符号,这会混淆链接器(因此链接器错误)。当链接器试图将对变量的引用与实际定义相匹配时,它不知道使用哪一个。

标题警卫不保护这一点。仅在每个翻译单元中定义了在标题保护中使用的宏。每当编译器开始编译新的.cpp文件(忽略统一构建等)时,这是一个新的翻译单元,本质上编译器从头开始,不知道以前定义的任何符号。

为了解决这个问题,只有在头文件中声明您的变量:

// extern specifies that the definition is elsewhere. 
extern int myGlobalVariable; 

然后定义该变量在一个源文件。

int myGlobalVariable;