Visual C++ Linking LNK2019 Error with a Precompiled Header - c++

I had a very weird problem with precompile header. The linker generates LNK2019: unresolved external symbol error when I implement method in .cpp file. However, the program could be compiled if I implement method in .h file. I happened to find out a solution but I have no idea about the root cause of this error.
My project structure looks like this
Solution
->project 1
->project 2
Project 1 has 3 files. A.h, A.cpp and stdafx.h
file A.h
#pragma once
class A
{
public:
int num;
A();
};
file A.cpp
#include "stdafx.h"
A::A()
{
num = 2;
}
file stdafx.h
...
#include "A.h"
...
In project 2. I want to use A class.
file whatever.cpp
#include "stdafx.h"
#include "../Project1/A.h"
...
A* a_obj = new A();
...
In compile time, the linker reports unresolved external symbol error for the A construction function. If I implement the constructor in A.h file. the project2 could be successful complied. I want to know, why can not put the implementation in A.cpp file? What is the right way to organize precompile header?
Thank you

Project 2 does not include the definition of the A constructor - one way to give it visibility of this is to include the definition in the header file (which you did).
Another way would be to include the A.cpp file in project 2.
A third way would be to export the A class, or the A constructor using a .def file or using the dllexport directive.
Put this in the precompiled header file:
// set up export import macros for client project use
// define the symbol "PROJ1" before including this file in project 1 only
// leave it undefined for other projects
#ifdef PROJ1
#define DLLEXP __declspec(dllexport)
#else
#define DLLEXP __declspec(dllimport)
#endif
Then declare the A class in the A header:
DLLEXP class A
{
public:
A();
...
};
Or:
class A
{
public:
DLLEXP A();
...
};

Related

C++ static bool variable

I can't understand something that causes LNK2005 errors that I've encountered.
Assume that you have a class A:
File A.h:
#ifndef A_H
#define A_H
class A{
public:
static foo(void);
private:
static bool m_someVar;
};
bool A::m_someVar = false;
#endif
File A.cpp:
#include "A.h"
void A::foo(){
m_someVar = true;
}
The code above causes a LNK 2005 however the following code doesn't:
File A.h:
#ifndef A_H
#define A_H
class A{
public:
static foo(void);
private:
static bool m_someVar;
};
#endif
File A.cpp:
#include "A.h"
bool A::m_someVar = false;
void A::foo(){
m_someVar = true;
}
Can someone explain why is this happening even though I have include guards? Should I also add #pragma once?
Thanks in advance.
EDIT: here's the compilation error:
"error LNK2005: "private: static bool GameManager::m_isGameOver" (?m_isGameOver#GameManager##0_NA) already defined in Execution.obj"
include guards(both #ifndef and #pragma) doesn't work across compilation units, which is one of the reasons you should never ever ever define anything in a header file, only declare them. Except for templates of course.
A compilation unit is one .cpp-file and all included headers. Each .cpp create an object file containing a middle stage binary representation of the code, this is the compilation stage. These object files are then linked together in the linking stage. Since each .cpp is handled separately in c++ if you have "float foo;" in header.hpp and both a.cpp and b.cpp include header.hpp, how would the compiler know which foo you mean when running the application?
A "static" variable inside a class declaration is actually a declaration for an extern variable that is in the scope of that class. Like every extern variable, it needs a definition in exactly one source file. Otherwise, the linker will complain about it.
You probably include the .h file from more than one source file, so you have more than one definition.

Why can't linker see my (definitely defined) externals?

I have a class with a header and a .cpp file. I declare my functions in the header, and define them in the .cpp file, as you would.
Header:
#pragma once
// my #includes
class CDNAGenerator
{
private:
// stuff
public:
CDNAGenerator(int, int);
~CDNAGenerator();
void FilterMeasurementsForOutliers(std::vector<double>& measurement_values);
// plenty more things
};
CPP:
CDNAGenerator::CDNAGenerator( int genes, int chromosomes )
{
// constructor code
}
void CDNAGenerator::FilterMeasurementsForOutliers(std::vector<double>& measurement_values)
{
// function code
}
Then, from a separate project in the same solution I reference the .h file (but not the .cpp - that seems to lead to multiple definition errors):
#include "..\CalibrationTool\DNAGenerator.h"
And call those functions:
CDNAGenerator* dnaGenerator = new CDNAGenerator(30, 0);
dnaGenerator->FilterMeasurementsForOutliers(values);
But I get unresolved external errors for CDNAGenerator::CDNAGenerator(int, int) and for CDNAGenerator::FilterMeasurementsForOutliers(class std::vector > &)
I thought that I had hooked everything up correctly, so can anyone suggest why I would be getting this linker error?
Add the CPP file to the project
What compiler are you using? Gcc (mingw) does'n supprort #pragma once Use code guards to avoid 'multiple definitions'.
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass {
...
}
#endif

A compile-time symbol was #defined but #ifdef does not see it

I have a test class declared in a header file and defined in a separate file. The class must compile differently under Windows, so i use #if defined ( _WINDOWS_ ). When I compile the cpp file which also contains #if defined ( _WINDOWS_ ), the file is compiled as if the symbol _WINDOWS_ was not defined, although it is defined in another file. When I compile the code, I am getting the following error:
Error Code : error lnk2019 unresolved external symbol public
source code
// test.h
class Test
{
public:
#if defined (_WINDOWS_)
void printwindow();
#endif
void notwindows();
};
//test.cpp
#include "test.h"
#if defined (_WINDOWS_)
void Test::printwindow()
{
cout << "i am windows ";
}
#endif
void test::notwindows()
{
cout << " not windows " ;
}
//main.cpp
#include "windows.h"
#include "test.h"
void main()
{
test t1 ;
t1.printwindow() // OK I have declared function so my _WINDOWS_ is available but when i run it i get
}
Error Code : error lnk2019 unresolved external symbol public
NOTE : if i define the function directly it works without any problem
// test.h
class Test
{
public:
#if defined (_WINDOWS_)
void printwindow(){couT << "i am window" }
#endif
void notwindows();
};
but I don't like this method. I prefer to define them in separate files (h and cpp).
It would be better for you to use _WIN32 instead of _WINDOWS_ for your conditional compilation test. _WINDOWS_ is defined only if windows.h has been included, while the compiler automatically defines _WIN32 for any build for a Windows target, regardless of what headers are included. In your situation, _WINDOWS_ is defined when you compile main.cpp but not when you compile test.cpp becuase test.cpp doesn't include windows.h.
Also, the _WINDOWS_ macro definition is an implementation detail of the windows.h header, and is not guaranteed to be used. For example, the MinGW version of windows.h does not define _WINDOWS_.
You need to include windows.h in your test.cpp file
When you compile test.cpp it does not have the _WINDOWS_ symbol defined. So it creates an object file without the windows function.
Then in test.hpp it uses the symbol because you included windows.h in main.cpp
If you change the order of the includes it will behave differentially. You should rethink the way how you want to select the windows version which does not depend on the order of includes (for example see the other answer about _WIN32_).
You can not change the code in an already compiled object file (test.cpp) using some define in another code file (main.cpp)

bool __cdecl func(void) already defined in func.obj

I'm getting
error LNK2005: "bool __cdecl hasLogin(void)" (?hasLogin##YA_NXZ) already defined in B.obj
error. func is declared in B.cpp file, and it's called from A.cpp file. B.cpp is included in A.cpp. Google says that it's not good to include cpp in antother cpp. If I copy/paste func in A.cpp there's no problem. How to solve tsis problem correctly?
PS I'm new to c++, so forgive if the question is dump.
Create a header file named B.h and add the following function declaration:
#ifndef _B_HEADER_
#define _B_HEADER_
bool hasLogin(void);
#endif
Instead of #include "B.cpp" in A.cpp use #include "B.h".
You should generally declare your classes/functions in .h (header) files, and implement them in .cpp files. It's also usually a good idea to put include guards in your .h files so including them multiple times is not a problem. That way your .cpp files can include any .h file without causing any conflicts.
An example; test.h
#ifndef TEST_H
#define TEST_H
class test {
public:
void bop();
}
bool hasLogin();
#endif
and the corresponding .cpp file
#include <iostream>
#include "test.h"
void test::bop() {
std::cout << "bop" << std::endl;
}
bool hasLogin() {
return false;
}
write #pragma once in the .cpp//.h where the error is coming, sometimes it avoids the error.

Visual Studio C++ Headers

I need to create structure like this:
// file main.h:
#pragma once
#ifndef _MAIN_H
#define _MAIN_H
#include <iostream>
#include "first.h"
#include "second.h"
#endif
// -----------------
// file first.h:
#pragma once
#ifndef _FIRST_H
#define _FIRST_H
#include "main.h" // because of using SomeFunction() in first.cpp
int SomeVar; // used in first.cpp
#endif
// -----------------
// file second.h:
#pragma once
#ifndef _SECOND_H
#define _SECOND_H
#include "main.h" // because of using SomeVar in second.cpp
int SomeFunction(); // implemented in second.cpp
#endif
// -----------------
By logic, if main.h will be compiled first, then each of this headers will be included only once and all variables/functions will be defined normally.
For example, this configuration compiled normally in IAR C++ Compiler, if set up in options "preinclude file" (not precompiled) to main.h.
But, in Visual Studio 2010 same structure causes linker errors like:
1>second.obj : error LNK2005: "int SomeVar" (?SomeVar##3HA) already defined in first.obj
1>second.obj : error LNK2005: "int SomeFunction" (?SomeFunction##3HA) already defined in first.obj
I think because of including files in alphabetic order. Apparently pragma- and define-guards are ignored by linker.
Errors can be fixed by additional header and external variables definitions, but this is hard and wrong way.
Question is: What should i do?
int SomeVar; // used in first.cpp
Variables should never be defined in headers. They should be declared with extern:
extern int SomeVar; // used in first.cpp
Then you can actually define them in "first.cpp" with int SomeVar;.
Also, "first.h" does not need to include "main.h". Headers should only include files if the definitions in that header absolutely need the contents of those files. The definitions in "first.h" do not need anything in "main.h". Therefore, it should not include it.
If "first.cpp" needs to include something from "second.h", then it is the responsibility of "first.cpp" to include it.
In the header file use extern keyword as:
//first.h
extern int SomeVar; //extern tells the compiler that definition is elsewhere
Then in .cpp file define it and use it:
//first.cpp
int SomeVar; //definition is here
As for SomeFunction, have you defined it header file itself? Re-check it. :-)