skip to Main Content

I am working on a project in Visual Studio and I decided to reorganize a lot of my code. Unfortunately, I am running into problems with linking different headers and their cpp files.

I have one header file that contains the libraries which get passed down a chain of header files. I have no idea how this works, but I am able to get the contents to populate throughout all of the headers:

/* vkInstance.h */
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
/* code used other header files */
/* vkGraphicsPipeline.h */
#include "vkInstance.h" // gains access to <GLFW/glfw3.h> within "vkInstance.h"

#include "component.h" // gets access to <GLFW/glfw3.h> through #include "vkInstance.h"
/* other headers similar to component.h */

When the component header’s content definitions are within the header file, elements of the <GLFW/glfw3.h> file are defined. The component header also has some macro definitions:

/* component.h */
#ifndef hComponent
#define hComponent

struct exampleStruct {
    exampleStruct(/* args */) {
        /* constructor code containing <GLFW/glfw3.h> items */
    }
    void exampleFunc(/* args */) {
        /* func code containing <GLFW/glfw3.h> items */
    }
}

#endif

While the above usage of <GLFW/glfw3.h> items is defined, I would like to move a lot of the definitions from my various header files to their cpp files, and that’s where I start to run into problems:

/* component.h */
#ifndef hComponent
#define hComponent

struct exampleStruct {
    exampleStruct(/* args */);
    void exampleFunc(/* args */) {
        /* func code containing <GLFW/glfw3.h> items */
    }
}

#endif

/* component.cpp */
#include "component.h"

exampleStruct::exampleStruct(/* args */) {
    /* constructor code containing <GLFW/glfw3.h> items */
}

void exampleStruct::exampleFunc(/* args */) {
    /* func code containing <GLFW/glfw3.h> items */
}

Whereas I had access to <GLFW/glfw3.h> definitions in the header file, I lose access to them in the cpp file, and the program fails to build.

I feel like I have a decent grasp on C++, but I am far from an expert, so please forgive me if I am missing an obvious solution. How can I avoid this problem and/or better organize my file structure?

2

Answers


  1. In your cpp+h example, you are still defining exampleFunc in your header file, AND now in your .cpp file too. That is an ODR (One Definition Rule) violation. You need to change your header file to simply declare exampleFunc, just like you did with the exampleStruct constructor.

    Also, since the .cpp file now uses things from
    <GLFW/glfw3.h>, it needs to #include that file. Unless the .h file also needs things from that file, then leave the #include there instead.

    Try something more like this, depending on what args actually need:

    component.h

    #ifndef hComponent
    #define hComponent
    
    #include <GLFW/glfw3.h>
    
    struct exampleStruct {
        exampleStruct(/* args */);
        void exampleFunc(/* args */);
    };
    
    #endif
    

    component.cpp

    #include "component.h"
    
    exampleStruct::exampleStruct(/* args */) {
        /* constructor code containing <GLFW/glfw3.h> items */
    }
    
    void exampleStruct::exampleFunc(/* args */) {
        /* func code containing <GLFW/glfw3.h> items */
    }
    

    Alternatively…

    component.h

    #ifndef hComponent
    #define hComponent
    
    struct exampleStruct {
        exampleStruct(/* args */);
        void exampleFunc(/* args */);
    };
    
    #endif
    

    component.cpp

    #include "component.h"
    #include <GLFW/glfw3.h>
    
    exampleStruct::exampleStruct(/* args */) {
        /* constructor code containing <GLFW/glfw3.h> items */
    }
    
    void exampleStruct::exampleFunc(/* args */) {
        /* func code containing <GLFW/glfw3.h> items */
    }
    
    Login or Signup to reply.
  2. I might be wrong here, but the code you wrote definitely has some obvious mistakes. The main thing here is in this part:

    /* vkGraphicsPipeline.h */
    #include "vkInstance.h" // gains access to <GLFW/glfw3.h> within "vkInstance.h"
    
    #include "component.h" // gets access to <GLFW/glfw3.h> through #include "vkInstance.h"
    /* other headers similar to component.h */
    

    the part where you told you’ll get access to glfw on component.h/component.cpp which is included in vkInstance.h is the mistake . include chains .. doesnt work like that. theyre like.. series of header includes that passes down the includes that the included headers contains.
    you were supposed to include vkInstance.h on component.h, not on a separate file and expect the code to magically link the includes together. if that was true, then the whole header chain would be invalid.

    try this and tell me if it doesn’t work:

    /* component.h */
    
    #ifndef hComponent
    #define hComponent
    
    #include"vkInstance.h"
    //this makes sure that vkInstance is included on component.h ,
    //which makes it able to include everything that was included
    //in vkInstance.h on component.h
    
    struct exampleStruct {
       exampleStruct(/* args */);
       void exampleFunc(/* args */) {
           /* func code containing <GLFW/glfw3.h> items */
       }
    }
    
    #endif
    
    /* component.cpp */
    #include "component.h"
    
    exampleStruct::exampleStruct(/* args */) {
       /* constructor code containing <GLFW/glfw3.h> items */
    }
    
    void exampleStruct::exampleFunc(/* args */) {
       /* func code containing <GLFW/glfw3.h> items */
    }
    

    you necessary don’t need to include them again and again if you can manage the chains

    and about that linker errors you’ll get, you might need to try linking the lib file to the program. the glfw has a glfw3.lib file on somewhere between the folders of it. try linking it and see if it still gives the error

    Good luck !!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search