Reputation: 3
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
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.
shader.cpp
- since you define SHADER_H
in shader.h
, the preprocessor will remove all the code from shader.cpp
before it hits the compilerRemove 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 */ }
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