float* 已在 Gameobject.obj 中定义

float* already defined in Gameobject.obj

本文关键字:定义 obj Gameobject 已在 float      更新时间:2023-10-16

>我有一个定义 2 个数组的头文件

//GeometricPrimitives.h
#ifndef GEOMETRIC_PRIMITIVES_H
#define GEOMETRIC_PRIMITIVES_H
#include <gl/glew.h>
GLfloat cubeVerts[] = {
//UP
0.5, 0.5, -0.5,
0.5, 0.5,  0.5,
-0.5, 0.5,  0.5,
-0.5, 0.5, -0.5,
//DOWN
0.5, -0.5, -0.5,
0.5, -0.5,  0.5,
-0.5, -0.5,  0.5,
-0.5, -0.5, -0.5,
//LEFT
-0.5,  0.5, -0.5,
-0.5,  0.5,  0.5,
-0.5, -0.5,  0.5,
-0.5, -0.5, -0.5,
//RIGHT
0.5,  0.5, -0.5,
0.5,  0.5,  0.5,
0.5, -0.5,  0.5,
0.5, -0.5, -0.5,
//FRONT
-0.5,  0.5, 0.5,
0.5,  0.5, 0.5,
0.5, -0.5, 0.5,
-0.5, -0.5, 0.5,
//BACK
-0.5,  0.5, -0.5,
0.5,  0.5, -0.5,
0.5, -0.5, -0.5,
-0.5, -0.5, -0.5,
};
GLbyte cubeIndices[] = {
1,2,3, 3,4,1,
5,6,7, 7,8,5,
9,10,11, 11,12,9,
13,14,15, 15,16,13,
17,18,19, 19,20,17,
21,22,23, 23,24,21
};
#endif // !GEOMETRIC_PRIMITIVES_H

和包含它的文件

//Mesh.h
#pragma once
#include <gl/glew.h>
#include <SDL_opengl.h>
#include <gl/GLU.h>
#include "ShaderProgram.h"
#include "GeometricPrimitives.h"
class Mesh
{
public:
Mesh();
void bind(ShaderProgram* program);
void init();
void render();
private:
GLuint vao;
GLuint vbo;
GLuint ibo;
GLfloat* vertices;
int verticesCount;
GLbyte* indices;
int indicesCount;
};

Mesh.h 包含在 GameObject.h 中,包含在 main.cpp 中。 当我编译时,我收到错误Error LNK2005 "float * cubeVerts" (?cubeVerts@@3PAMA) already defined in GameObject.obj

我读到这源于文件在不同的 obj-s 中多次添加的问题,然后这些文件合并在一起给出多个定义。如何使用这些静态值创建此标头并在需要它们的地方使用它们?

正如你自己建议的那样,你可以让你的数组成为静态的。这样,每个翻译单元将具有同一数组的相同副本,但数组在翻译单元之外不可见。所以,链接器会很高兴。但也许您不会高兴,因为同一个数组将占用两倍的内存(如果您将其包含在其他地方,则可能会占用更多内存(。

因此,另一种方法是将数组的定义放入 GeometricPrimitives.cpp并在 GeometricPrimitives.h 中只保留声明。这样,数组将创建一次,它将在整个应用程序中使用。

另外,不要忘记输入 const 关键字,如果你的数组应该是 const。

如果可以使用 C++17 或更高版本,另一种解决方案是将数组声明为inline变量。这样,它们可以在包含在多个翻译单元中的标头中定义,但与static对象不同,所有对象都将引用所有翻译单元中的同一单个实例。

正如 rhaport 所说,如果它们是只读数据,请确保也进行这些const,因为您不希望能够在一个翻译单元中意外弄乱它们的值而另一个翻译单元不知道它。