0

I've made a library when i try and use it in another project i get a LNK2005 error.

Structs.h

#pragma once
#ifndef STRUCTS_H
#define STRUCTS_H

#include <vector>
#include <string>

namespace Structs
{
    struct GameObject
    {
        std::string name;

        struct PosPoints
        {
            double px;
            double py;
        };

        std::vector<PosPoints> Points;

        double centroid[2];
        bool active;
        bool init;
    };
    std::vector<GameObject> objects;
}

#endif

Structs.cpp

#include "stdafx.h"
#include "Structs.h"

struct Structs::GameObject gameObject;
std::vector<Structs::GameObject> objects;

CoreFuncs.cpp

#include "stdafx.h"
#include "CoreFuncs.h"
#include "Structs.h"
#include <GLFW/glfw3.h>

//render
extern struct Structs::GameObject gameObject;
void RenderShapes()
{
    for (int i = 0; i < Structs::objects.size(); i++)
    {
        for (int j = 0; j < Structs::objects[i].Points.size()-1; j++)
        {
            glBegin(GL_LINES);
            glVertex3f(Structs::objects[i].Points[j].px, Structs::objects[i].Points[j].py, 0);
            glVertex3f(Structs::objects[i].Points[j + 1].px, Structs::objects[i].Points[j + 1].py, 0);

            glVertex3f(0.1, 0.1, 0);
            glVertex3f(0.9, 0.9, 0);

            glEnd();
        }
    }   
}

image

The issue stops happening when i comment out the #include "Structs.h" in CoreFuncs.cpp So I assume that inlcude is what is causing the issues. I have looked around and found many sources using extern but i cant seem to get it working here.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    Inside `namespace Structs` you have `std::vector objects;`. It is a definition, not a declaration. – KamilCuk Sep 04 '19 at 00:39

1 Answers1

1

Your header file is declaring an actual variable instance named objects. Every translation unit that #includes your header file will get its own copy of that variable. So when you link multiple such units together into a single executable, you will get errors about all of the duplicate variables.

It looks like you want the variable to be instantiated only once in your Structs.cpp file and then shared by your other units. So the variable needs to be declared as extern in your header file. You should also move the extern declaration of the gameObject variable from out of your CoreFuncs.cpp file and place it in your header file, too.

Structs.h

#pragma once
#ifndef STRUCTS_H
#define STRUCTS_H

#include <vector>
#include <string>

namespace Structs
{
    struct GameObject
    {
        std::string name;

        struct PosPoints
        {
            double px;
            double py;
        };

        std::vector<PosPoints> Points;

        double centroid[2];
        bool active;
        bool init;
    };

    extern std::vector<GameObject> objects;
    extern GameObject gameObject;
}

#endif

Structs.cpp

#include "stdafx.h"
#include "Structs.h"

namespace Structs {
    std::vector<GameObject> objects;
    GameObject gameObject;
}

CoreFuncs.cpp

#include "stdafx.h"
#include "CoreFuncs.h"
#include "Structs.h"
#include <GLFW/glfw3.h>

//render
void RenderShapes()
{
    for (size_t i = 0; i < Structs::objects.size(); ++i)
    {
        Structs::GameObject &go = Structs::objects[i];

        for (size_t j = 0; j < go.Points.size()-1; ++j)
        {
            PosPoints &pt1 = go.Points[j];
            PosPoints &pt2 = go.Points[j + 1];

            glBegin(GL_LINES);

            glVertex3f(pt1.px, pt1.py, 0);
            glVertex3f(pt2.px, pt2.py, 0);

            glVertex3f(0.1, 0.1, 0);
            glVertex3f(0.9, 0.9, 0);

            glEnd();
        }
    }   
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I have made both of those changes and i still get an unresolved external http://prntscr.com/p1gv70 – Dylan Robertson Sep 04 '19 at 00:51
  • 1
    @DylanRobertson "already defined" and "unresolved external" are two different kinds of errors. Your question's title does not match its body. – Remy Lebeau Sep 04 '19 at 00:54
  • No, i meant after making the changes you sent i got that error. At the time of positing the error was http://prntscr.com/p1gzwd – Dylan Robertson Sep 04 '19 at 01:09