2010-06-24 95 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;