2010-06-24 6 views
5

Quiero implementar una función con OpenGL para renderizar un cilindro en C++. La firma de mi función es la siguiente:Referencia a una matriz de dos dimesiones

#define POINTS_NUM 15 
#define DEMESION 3 

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

Quiero utilizar una referencia a una matriz bidimensional para limitar la entrada del usuario, pero un comportamiento extraño está sucediendo. Cuando implemente la función declarada como anteriormente, se produce un error de vinculador:

Error 1 error LNK2005: "float (* vase)[3]" ([email protected]@3PAY02MA) already defined in shapes.obj vase.obj VaseAndAnimation

Aquí vase se define como:

GLfloat vase[ POINTS_NUM ][ DEMESION ]; 

Al principio, pensé que había algo malo en la última dimensión. Así que lo omití en mi segunda prueba. Esta declaración momento de mi función es la siguiente:

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

Ahora un error en tiempo de compilación se produce cuando se invoca como (vase definición no se cambia):

drawCylinder(10, 10, vase); 

Error de compilación:

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

De este error, puedo ver que el parámetro vertices se trata realmente como una referencia a una matriz bidimensional, pero ¿por qué vase se analiza como float (* vase)[3] en mi primera versión?

Mi IDE es Visual Studio 2008. No lo he probado con GCC; ¿ese comportamiento es dependiente del compilador?

Espero que alguien pueda echarme una mano para deshacerse de la trampa.

+0

posible duplicado de [¿Cómo se pasa una referencia a una matriz bidimensional a una función?] (Http://stackoverflow.com/questions/404232/how-do-i-pass-a- reference-to-a-two-dimensional-array-to-a-function) –

Respuesta

2

Su primera declaración está bien. Parece ser que ha definido vase en un archivo de cabecera.

+0

Sí, tienes razón. Después de revisar cuidadosamente mi código, encuentro que el jarrón se define justo antes de la declaración de la función. Pero ¿por qué no puedo definir la matriz en el archivo de encabezado? No sabía ningún límite sobre eso. Gracias. –

+0

Su encabezado está incluido en varios archivos cpp. Esto significa que 'florero' se definirá varias veces. Puede declararlo en un encabezado y luego definirlo en uno de los archivos cpp. –

+0

Sí, conozco este caso. Pero, he definido una macro para evitar duplicados incluidos. Todavía hay el problema. –

1

Parece que el problema es que vase está siendo definido en un archivo de encabezado. Solo debe declarar variables en archivos de encabezado.

Esto causa un problema porque las definiciones múltiples producen múltiples del mismo símbolo, lo que confunde al enlazador (de ahí el error del enlazador). Cuando el vinculador intenta hacer coincidir las referencias a la variable con la definición real, no sabe cuál usar.

Los protectores de cabecera no protegen contra esto. Las macros utilizadas en un protector de encabezado solo están definidas por unidad de traducción. Cada vez que el compilador comienza a compilar un nuevo archivo .cpp (ignorando las compilaciones de unidades, etc.), esa es una nueva unidad de traducción y, esencialmente, el compilador comienza desde cero, sin conocer los símbolos que se han definido previamente.

Para solucionar esto, sólo se declarará sus variables en los archivos de cabecera:

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

y luego definir esa variable en uno archivo de origen.

int myGlobalVariable; 
Cuestiones relacionadas