在名为gl_ext.h的文件中,我有以下内容:
#ifndef GLEXT_H_INCLUDED
#define GLEXT_H_INCLUDED
#include <stdexcept>
#ifdef WIN32
#include <Windows.h>
#include <GL/GL.h>
#include <GL/glext.h>
# define glGetProcAddress(arg) wglGetProcAddress(arg)
#elif __linux__
#include <GL/gl.h>
#include <GL/glext.h>
# include <GL/glx.h>
# define glGetProcAddress(arg) glXGetProcAddress((const GLubyte*)arg)
#endif
PFNGLCREATESHADERPROC glCreateShader = 0;
namespace glext
{
bool load_gl_extensions()
{
static bool loaded = false;
if (loaded) {
return true;
}
if (!glCreateShader) {
glCreateShader =
(PFNGLCREATESHADERPROC)(glGetProcAddress("glCreateShader"));
if (!glCreateShader) {
throw "Failed to load glCreateShader";
}
}
}
}
#endif
使用以下.pro文件在qt creator中构建时
QT += core gui opengl
TEMPLATE = app
TARGET = GLExtensions
INCLUDEPATH += .
LIBS += -lGL
HEADERS += gl_ext.h \
qtrenderer.h
SOURCES += main.cpp \
qtrenderer.cpp
此“标题库”的用法如下: main.cpp中
#include <QtGui/QApplication>
#include "qtrenderer.h"
int main(int argc, char * argv[]) {
QApplication app(argc, argv);
QtRenderer *renderer = new QtRenderer();
renderer->show();
app.exec();
}
qtrenderer.h
#ifndef QTRENDERER_H_INCLUDED
#define QTRENDERER_H_INCLUDED
#include <QtCore/QObject>
#include <QtOpenGL/QGLWidget>
#include <gl_ext.h>
class QtRenderer : public QGLWidget
{
Q_OBJECT
private:
QtRenderer(const QtRenderer &other);
QtRenderer &operator = (const QtRenderer &other);
protected:
virtual void paintGL();
virtual void initializeGL();
public:
QtRenderer();
~QtRenderer();
public slots:
virtual void updateGL();
};
#endif
qtrenderer.cpp
#include "qtrenderer.h"
QtRenderer::QtRenderer() :
QGLWidget() {
}
QtRenderer::~QtRenderer() {
}
void QtRenderer::initializeGL() {
try {
glext::load_gl_extensions();
} catch (...) {
throw std::runtime_error("Failed to load needed extensions.");
}
}
void QtRenderer::paintGL() {
swapBuffers();
}
void QtRenderer::updateGL() {
paintGL();
}
使用
构建此源代码时gcc (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2)
我收到以下构建错误:
qtrenderer.o: In function `glext::load_gl_extensions()':
/home/mehoggan/Devel/test_gl/./gl_ext.h:28: multiple definition of `glCreateShader'
main.o:/home/mehoggan/Devel/test_gl/./gl_ext.h:28: first defined here
为什么会这样?
答案 0 :(得分:3)
好吧,标题gl_ext.h包含多次。请记住,#include类似于以复制和粘贴方式将#include语句替换为文件内容。
您应该将load_gl_extensions()的实现放入.cpp文件中,并将声明只放入头文件中。
gl_ext.h:
//...
extern PFNGLCREATESHADERPROC glCreateShader;
namespace glext
{
bool load_gl_extensions();
}
gl_ext.cpp:
#include "gl_ext.h"
PFNGLCREATESHADERPROC glCreateShader = 0;
namespace glext
{
bool load_gl_extensions()
{
static bool loaded = false;
if (loaded) {
return true;
}
if (!glCreateShader) {
glCreateShader =
(PFNGLCREATESHADERPROC)(glGetProcAddress("glCreateShader"));
if (!glCreateShader) {
throw "Failed to load glCreateShader";
}
}
}
}
extern
告诉编译器变量/函数指针(glCreateShader)放在不同的编译单元中(每个.cpp文件被编译为不同的单元)。然后链接器插入变量的正确内存地址。也许您应该对C ++编译和链接的工作方式进行一些研究。
答案 1 :(得分:0)
问题的解决方案包括使方法内联并将函数指针声明为静态。