I have started to write some code for a vulkan application and after a while I have splitted up my code in multiple files for example a File full of the most important global Variables.After that I got a lot of errors with included files but I was able to fix these.... I think. But after that there were many linker errors with my global variables and some functions and I have tried many thinks but nothing helped very much. Here are some Files of my Project:
Main.cpp:
#ifndef Security_V_StartUpInc
#define Security_V_StartUpInc
#include "Vulkan_Startup.h"
#endif // !Security_V.StartUpInc
int main() {
VulkanUtility::main_Start_Vulkan__();
__Pause;
return 0;
}
Vulkan_Startup.h:
#pragma once
#ifndef Security_VulkanLibInc
#define Security_VulkanLibInc
#include <vulkan/vulkan.h>
#endif // !Security_VulkanLibInc
#ifndef Security_StructVarinc
#define Security_StructVarinc
#include "StructVariables.h"
#endif // !Security_StructVarinc
#ifndef Security_VariblesInc
#define Security_VariblesInc
#include "Variables.h"
#endif // !Security_VariblesInc
#define SpecSecure(var)\
if(var==2){Variables::Global::Err.PrinttoLog(12,Variables::Global::Errorregister);return 2;}
#define Advancedsecure(var) \
if(var==2){Variables::Global::Err.PrinttoLog(11,Variables::Global::Errorregister);return 1;}
namespace VulkanUtility {
inline void printLog(int result, int Stat);
inline void printLog(VkResult result, int Stat);
inline int InitVulkan__();
inline int main_Start_Vulkan__();
}
Vulkan_Startup.cpp
#include "Vulkan_Startup.h"
inline void VulkanUtility::printLog(int result, int Stat) {
if (result != 0) {
Variables::Global::Err.PrinttoLog(Stat * 2 - 1, Variables::Global::Errorregister);
}
else {
Variables::Global::Err.PrinttoLog(Stat * 2, Variables::Global::Errorregister);
}
}
inline void VulkanUtility::printLog(VkResult result, int Stat) {
if (result != VK_SUCCESS) {
Variables::Global::Err.PrinttoLog(Stat * 2 - 1, Variables::Global::Errorregister);
}
else {
Variables::Global::Err.PrinttoLog(Stat * 2, Variables::Global::Errorregister);
}
}
inline int VulkanUtility::InitVulkan__() {
Variables::Global::CP.Number_of_Graphical_Devices = 0;
Variables::Global::VT.AppInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
Variables::Global::VT.AppInfo.pNext = NULL;
//...
return 0;
}
inline int VulkanUtility:: main_Start_Vulkan__() {
InitVulkan__();
int res;
VkPhysicalDeviceProperties* PhysicalDeviceProp = nullptr;
VkPhysicalDeviceFeatures* PhysikalDeviceFeat = nullptr;
VkPhysicalDeviceMemoryProperties* Memprop;
VkQueueFamilyProperties* Queue;
res = Variables::Global::CP.GetProperties(0, PhysicalDeviceProp);
if (Variables::Global::EnableLog) { printLog(res, 4); Advancedsecure(res) };
res = Variables::Global::CP.GetFeatures(0, PhysikalDeviceFeat);
if (Variables::Global::EnableLog) { printLog(res, 5); Advancedsecure(res) };
res = Variables::Global::CP.GetMemoryProperties(0, Memprop);
if (Variables::Global::EnableLog) { printLog(res, 7); Advancedsecure(res) };
res = Variables::Global::CP.getQueueProperties(0, Queue);
if (Variables::Global::EnableLog) { printLog(res, 8); SpecSecure(res) }
__Pause;
return 0;
}
StructVariables.h
#pragma once
#define Security_StructVarinc
#ifndef Security_VulkanLibInc
#define Security_VulkanLibInc
#include <vulkan/vulkan.h>
#endif // !Security_VulkanLibInc
#ifndef Security_DefInc
#define Security_DefInc
#include "Define.h"
#endif // !Security_StructVarInc
#ifndef Security_MapVarInc
#define Security_MapVarInc
#include "MapLib.h"
#endif // !Security_StructVarInc
#ifndef Security_Errorhandlerinc
#define Security_Errorhandlerinc
#include "Errorhandler.h"
#endif // Security_Errorhandlerinc
namespace Variables
{
namespace Predefined_Structs {
struct Vinstance
{
VkApplicationInfo AppInfo;
VkInstanceCreateInfo InsInfo;
VkInstance Instance;
};
struct ComputerSpecs
{
uint32_t* Queuecount;
uint32_t Number_of_Graphical_Devices;
VkPhysicalDevice* Devices;
VkPhysicalDeviceProperties* Properties;
VkPhysicalDeviceFeatures* Features;
VkPhysicalDeviceMemoryProperties* Memprop;
VkQueueFamilyProperties* Queueprop;
ComputerSpecs();
void Set();
void Advancedset();
int Setqueue();
int GetProperties(int devicecount, VkPhysicalDeviceProperties*& Properties);
int GetFeatures(int devicecount, VkPhysicalDeviceFeatures*& Features);
int GetMemoryProperties(int Devicecount, VkPhysicalDeviceMemoryProperties*& Memprop);
int getQueueProperties(int Devicecount, VkQueueFamilyProperties*& Queue);
~ComputerSpecs();
};
struct Errorreg {
Allocater::ExclMapLib<String>* Register;
Errorreg();
~Errorreg();
};
}
}
StructVariables.cpp
#include "StructVariables.h"
Variables::Predefined_Structs::ComputerSpecs::ComputerSpecs()
{
Number_of_Graphical_Devices = 0;
Queuecount = nullptr;
VkPhysicalDevice* Devices = nullptr;
}
void Variables::Predefined_Structs::ComputerSpecs::Set()
{
Devices = new VkPhysicalDevice[Number_of_Graphical_Devices];
Properties = nullptr;
Features = nullptr;
Memprop = nullptr;
Queueprop = nullptr;
}
void Variables::Predefined_Structs::ComputerSpecs::Advancedset()
{
Properties = new VkPhysicalDeviceProperties[Number_of_Graphical_Devices];
Features = new VkPhysicalDeviceFeatures[Number_of_Graphical_Devices];
Memprop = new VkPhysicalDeviceMemoryProperties[Number_of_Graphical_Devices];
for (int i = 0; i < Number_of_Graphical_Devices; i++) {
vkGetPhysicalDeviceProperties(Devices[i], Properties);
vkGetPhysicalDeviceFeatures(Devices[i], Features);
vkGetPhysicalDeviceMemoryProperties(Devices[i], Memprop);
}
Setqueue();
}
int Variables::Predefined_Structs::ComputerSpecs::Setqueue()
{
if (Devices != nullptr && Number_of_Graphical_Devices != 0) {
Queuecount = new uint32_t[Number_of_Graphical_Devices];
for (int i = 0; i < Number_of_Graphical_Devices; i++) {
vkGetPhysicalDeviceQueueFamilyProperties(Devices[i], &Queuecount[i], nullptr);
Queueprop = new VkQueueFamilyProperties[Queuecount[i]];
vkGetPhysicalDeviceQueueFamilyProperties(Devices[i], &Queuecount[i], Queueprop);
}
return 0;
}
return 1;
}
int Variables::Predefined_Structs::ComputerSpecs::GetProperties(int devicecount, VkPhysicalDeviceProperties*& Properties)
{
if (devicecount >= Number_of_Graphical_Devices) { return 1; }
else if (this->Properties != nullptr) {
Properties = this->Properties;
return 0;
}
return 2;
}
int Variables::Predefined_Structs::ComputerSpecs::GetFeatures(int devicecount, VkPhysicalDeviceFeatures*& Features)
{
if (devicecount >= Number_of_Graphical_Devices) { return 1; }
else if (this->Features != nullptr) {
Features = this->Features;
return 0;
}
return 2;
}
int Variables::Predefined_Structs::ComputerSpecs::GetMemoryProperties(int Devicecount, VkPhysicalDeviceMemoryProperties*& Memprop)
{
if (Devicecount >= Number_of_Graphical_Devices) { return 1; }
else if (this->Memprop != nullptr) {
Memprop = this->Memprop; return 0;
}
return 2;
}
int Variables::Predefined_Structs::ComputerSpecs::getQueueProperties(int Devicecount, VkQueueFamilyProperties*& Queue)
{
if (Devicecount >= Number_of_Graphical_Devices) { return 1; }
else if (this->Queueprop != nullptr) {
Queue = this->Queueprop; return 0;
}
return 2;
}
Variables::Predefined_Structs::ComputerSpecs::~ComputerSpecs()
{
delete[] Memprop;
delete[] Features;
delete[] Properties;
delete[] Devices;
delete[] Queuecount;
delete[] Queueprop;
}
Variables::Predefined_Structs::Errorreg::Errorreg()
{
Register = new Allocater::ExclMapLib<String>(100);
Register->CreateShelf(1, "Unable_to_create_Vulkan_Instance");
Register->CreateShelf(2, "Succesfully created Vulkan Instance");
//....
}
Variables::Predefined_Structs::Errorreg::~Errorreg()
{
Register->Test();
delete Register;
}
Variables.h
#pragma once
#ifndef Security_StructVarinc
#define Security_StructVarinc
#include "StructVariables.h"
#endif
#ifndef Security_Errorhandlerinc
define Security_Errorhandlerinc
#include "Errorhandler.h"
#endif // !Security_Errorhandlerinc
namespace Variables {
namespace Predefined_Structs
{
struct Vinstance;
struct ComputerSpecs;
struct Errorreg;
}
}
namespace Variables {
namespace Global
{
extern bool EnableLog ;
extern Variables::Predefined_Structs::Vinstance VT;
extern Variables::Predefined_Structs::ComputerSpecs CP;
extern Variables::Predefined_Structs::Errorreg Errorregister;
extern Handling::Errorhandler Err;
}
}
...And some other files.
In this Configuration I get the Error:LNK1120,LNK2019-... ""int cdecl VulkanUtility::main_Start_Vulkan(void)" (?main_Start_Vulkan__@VulkanUtility@@YAHXZ)" in Funktion "_main" ;
But if I put the code of the Vulkan_Startup.cpp file inside of the Vulkan_Startup.h(without the "#include"Vulkan_Startup.h"" at the top) file i get these errors: again LNK 1120 but with 5x LNK2001:
...""class Handling::Errorhandler Variables::Global::Err" (?Err@Global@Variables@@3VErrorhandler@Handling@@A)".
... ""bool Variables::Global::EnableLog" (?EnableLog@Global@Variables@@3_NA)".
... ""struct Variables::Predefined_Structs::ComputerSpecs Variables::Global::CP" (?CP@Global@Variables@@3UComputerSpecs@Predefined_Structs@2@A)".
... ""struct Variables::Predefined_Structs::Errorreg Variables::Global::Errorregister" (?Errorregister@Global@Variables@@3UErrorreg@Predefined_Structs@2@A)".
... ""struct Variables::Predefined_Structs::Vinstance Variables::Global::VT" (?VT@Global@Variables@@3UVinstance@Predefined_Structs@2@A)".
Sorry for maybe bad english at some points.
Thanks for your help.
Edit: I have now deleted every global variables and now there arent any LNK 2001 errors-> Every global variables are now functions params and defined in the main file. But there are also the error LNK 2019 in this code : But if I put the definitions of the VulkanStartup.cpp file into the header file everything works fine: But I dont want to put just the definition into the header file because I want to learn what I shouldnt do next time and not to leave this error behind me without learning anything. Also thanks for your help until this point!