Flava Snoop
Flava Snoop

Reputation: 3

LNK 2019 "Unresolved External Symbol" Error (C++ OpenGL)

I'm relatively new to C++ and I've been having some problems while making classes in files. I'm trying to call a constructor from a separate class, Shader, and use a method in said class. However whenever I try to build the solution, I get the following error:

Error   2   error LNK2019: unresolved external symbol "public: void __thiscall Shader::Use(void)" (?Use@Shader@@QAEXXZ) referenced in function _main    
Error   1   error LNK2019: unresolved external symbol "public: __thiscall Shader::Shader(char const *,char const *)" (??0Shader@@QAE@PBD0@Z) referenced in function _main

I know that there is nothing wrong with the Project Properties Linker or the rendering system because I've rendered things before with my current configuration, so I figure it must have something to do with the code but I can't figure it out:

main.cpp

#include <iostream>

// GLEW
#define GLEW_STATIC
#include <GL/glew.h>

// GLFW
#include <GLFW/glfw3.h>

// Other includes
#include "Shader.h"

int main ()
{

(... Window Setup ...)


// Build and compile shader program
Shader shaders ("shader.vs", "shader.frag");


(... Set up vertex data (and buffer(s)) and attribute pointers ...)

// Game loop
while(!glfwWindowShouldClose (window))
{
    glfwPollEvents ();

    ourShader.Use ();

(... Draw triangle ...)

    glfwSwapBuffers (window);
}
(... De-allocate all resources ...)

(... Terminate window ...)
return 0;
}

Shader.h

#ifndef SHADER_H
#define SHADER_H

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>

#include <GL/glew.h>

class Shader
{
public:

GLuint Program;
Shader(const GLchar* vertexPath, const GLchar* fragmentPath);
void Use ();

};

#endif

Shader.cpp

#ifndef SHADER_H
#define SHADER_H

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>

#include <GL/glew.h>

#include "Shader.h"

class Shader
{
public:
GLuint Program;
Shader::Shader(const GLchar* vertexPath, const GLchar* fragmentPath)
{
    (... 1. Retrieve the vertex/fragment source code from filePath ...)

    (... 2. Compile shaders ...)

    (... 3. Link shader program ...)

    (... 4. Delete shaders after usage ...)
}

void Shader::Use ()
{
    (... Use current shader program ...)
}
};

#endif

Any help would be greatly appreciated. If any more code is needed I can provide. Thanks in advance!

Upvotes: 0

Views: 1648

Answers (1)

Alfred Bratterud
Alfred Bratterud

Reputation: 533

Firstly, if this compiles it's because the inclusion guard in shader.cpp removes the erroneous code. Secondly, if you remove the inclusion guard from shader.cpp (which you should) this won't compile, because the class is declared twice in shader.cpp (via #include "Shader.h"). The linking error in turn occurs because main.cpp isn't being linked with a compiled version of shader.cpp.

  1. Remove the inclusion guard from shader.cpp - since you define SHADER_H in shader.h, the preprocessor will remove all the code from shader.cpp before it hits the compiler
  2. Remove the class declaration from shader.cpp, but keep the definitions of all members of the shader class. Just keep shader.cpp simple, like so:

    #include "shader.h"
    
    Shader::Shader(const GLchar* vertexPath, const GLchar* fragmentPath)
    { /*..body */ }
    
    Shader::use()
    { /*..body */ }
    
  3. Make sure you link main with the compiled version of shader, e.g. g++ main.cpp shader.o, assuming shader was compiled separately, e.g. g++ -c shader.cpp

Upvotes: 1

Related Questions