I have the following files
file1_moduleA.hpp
file1_moduleA.cpp
sharedFile.hpp
file1_moduleB.cpp
//sharedFile.hpp
extern CustomClass *doSomething(CustomClass *var1, const char *var2);
extern CustomClass *doSomethingElse(const char *var1);
template <class MYCLASS_A>
void myFunction(CustomClass *var1, const char* var2){
assert(somthing);
if (condition){
new (MYCLASS_A);
}
}
//file1_moduleA.cpp
#include "sharedFile.hpp"
// Contains the definitions of doSomething and doSomethingElse among others
//file1_moduleA.hpp
// Other declarations
//file1_moduleB.cpp
#include"sharedFile.hpp"
//...SNIPPETS OF CODE
void someFunction(CustomClass* var1){
doSomething(var1, "FOO");
}
//...
The following are in one Visual Studio Project, Project A:
file1_moduleA.hpp, file1_moduleA.cpp and sharedFile.hpp
The following are in another VS Project, Project B:
file1_moduleB.cpp, file1_moduleB.hpp
Project A compiles and links perfectly, whereas Project B compiles but gives an unresolved symbol for CustomClass *doSomething(CustomClass *var1, const char *var2) at someFunction in file1_moduleB.cpp
I have tried defining the function with and without extern; tried using a separate file for the template in file1_moduleA.hpp; tried inducing dependency between ProjectB and ProjectA in VS, but nothing seems to work. I am unsure why the definition is not being found during linking. ProjectA.lib however, is being created.
Any help in this regard would be appreciated.
if you are using visual studio, and these are different project, then make project B dependent upon project A.
Right click on the solution.
Go to project dependencies.
Choose Project B.
Click Project A (making project B dependent upon Project A)
rebuild.
Did you include shared file in project B?
Related
I try to implement google test framework for verifing dll library into my existed solution by visual studio community 2019. Basically, I have 3 files:
Source code is built in single dll project.
FooCmdMgr.cpp
FooCmdMgr.h
Unit test code using the latest google test framework in other project in a same solution with source code.
FooCmdMgr_Test.cpp
FooCmdMgr.h
class FooCmdMgr
{
public:
FooCmdMgr(const FooCmdMgr&) = delete;
FooCmdMgr& operator=(const FooCmdMgr& ) = delete;
bool func_1() {
return true;
}
private:
FooCmdMgr();
~FooCmdMgr();
static FooCmdMgr& Instance ( );
friend FooCmdMgr& GetFooCmdMgr ( );
};
inline FooCmdMgr& GetFooCmdMgr()
{
return FooCmdMgr::Instance();
}
FooCmdMgr_Test.cpp
#include "stdafx.h"
#include "../FooCmdMgr.h"
TEST_F(CJobChangeTestFixture, UnitTest2) {
FooCmdMgr& FooCmdMgr = ICmdEx::FooCmdMgr();
//bool bRet = FooCmdMgr.func_1();
//EXPECT_EQ(bRet, true);
}
Solution was compliled successful but linker was not OK.
It shown error LNK2019 something likes this:
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "private: static class ICmdEx::FooCmdMgr & __cdecl ICmdEx::FooCmdMgr::Instance(void)" (?Instance#FooCmdMgr#ICmdEx##CAAEAV12#XZ) referenced in function "class ICmdEx::FooCmdMgr & __cdecl ICmdEx::GetIKYCmdMgr(void)" (?GetIKYCmdMgr#ICmdEx##YAAEAVFooCmdMgr#1#XZ) IEditorDll_GTest E:\work\project\UnitTest\FooCmdMgr_Test.obj
Project structure
E:\work\project\FooCmdMgr.vcxproj
E:\work\project\FooCmdMgr.cpp
E:\work\project\FooCmdMgr.h
E:\work\project\FooCmdMgr.dll
E:\work\project\FooCmdMgr.lib
Google test project
E:\work\project\UnitTest\FooCmdMgr_Test.vcxproj
E:\work\project\UnitTest\FooCmdMgr_Test.cpp
I also change the configuration of linker in gtest project
General/Additional Library Directories
$(ProjectDir)../
Input/Additional Dependencies/
FooCmdMgr.lib
I am struggling to figure out what happened with linker? Please give me advise.
your Foo class should be like this
#pragma once
#ifdef PROJECT1_EXPORTS
#define PROJECT1_API __declspec(dllexport)
#else
#define PROJECT1_API __declspec(dllimport)
#endif
class PROJECT1_API Foo
{
};
PROJECT1_EXPORTS is defined in your main source PREPROCESSOR project.
and it will NOT be define in your Test project
I had the same problem and fixed it by adding the output .obj/.lib files to the dependencies of the test project as described here: https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2015/test/unit-testing-existing-cpp-applications-with-test-explorer?view=vs-2015&redirectedfrom=MSDN#objectRef
I have Visual Studio 2022 with Google Test, and for me, it was enough to perform only steps 2 to 4 from the instruction. I.e.:
In Solution Explorer, on the shortcut menu of the test project, choose Properties. The project properties window opens.
Choose Configuration Properties, Linker, Input, Additional Dependencies.
Choose Edit, and add the names of the .obj or .lib files. Do not use the full path names.
Choose Configuration Properties, Linker, General, Additional Library Directories.
Choose Edit, and add the directory path of the .obj or .lib files. The path is typically within the build folder of the project under test.
I use NVIDIA CUDA, so needed to add its .lib file and path too.
I'm facing the error when I'm linking an external library and code with the current project. You will understand the problem by this example.
//foo.h
namespace LMS
{
class foo
{
foo(); //implementation in cpp
foo(int dummy) //implemented here
{
//something
}
};
} // namespace LMS
//foo.cpp
#include"foo.h"
namespace LMS
{
foo::foo()
{
//something
}
} // namespace LMS
//externalProgram.h
#include "foo.h"
LMS::foo *ptr;
ptr = new LMS::foo(); //Linking error: LNK 2019
ptr = new LMS::foo(2); //No error
Now the problem is that the external program doesn't know about the foo.cpp and the implementation of class foo methods in it. I'm currently using VS2019 and using two projects in the same solution. I've tried several ways to correct this but it didn't work out. The current way I'm seeing is to implement all the functions in header files.
EDIT: I've already linked the files!!
You should be able to mark your externalProgram project as dependent on the foo project. This will link foo.o in with external program.
Using the UI you will select this in
Project > Project Dependencies : Depends on ...
If that is correct, then the problem is more subtle, sometimes just a simple typo. At this point you want to use the command line tools to break apart the library and confirm the object files, and break apart the object files and confirm the symbols within. A ten year old SO posting discusses using lib.exe to example the library file. The dumpbin tool has a /symbols option that might also be handy for looking at the actual code generated.
I work on VS2015.
I have C++ project A that has a few files and MyClass.h. It's built with /clr flag.
I have another C++ console project B and is also built with /clr flag. The B has B.cpp with the following content:
//B.cpp
#include "MyClass.h"
void main()
{
MyClass* obj = new MyClass();
}
I succesfully can build project B. But, when I add project A as reference (right click->Add Reference) to project B, I suddenly get redefinition error of a class that's definied in a file in project A.
How adding a reference can cause such error?
UPDATE1
All header files have "header guard".
UPDATE2
I thought ProjectA is console and ProjectB is static lib. But, it was late at night and I didn't notice that I created both ProjectA and ProjectB as console applications.
I know that I need to export MyClass if ProjectB is a dll so I could use it in ProjectA. The example maybe stupid but since I got this by mistake I still want to understand why I get the redifinition error in this case. I've uploaded the test to here.
ProjectA has reference to ProjectB.
//ProjectA.cpp
#include "MyHeader.h"
int main()
{
return 0;
}
//ProjectB.cpp
#include "MyHeader.h"
//MyHeader.h
#pragma once
public enum class MyClass : int
{
};
If I remove the reference to ProjectB or I comment out #include "MyHeader.h" I do not get the redifinition error anymore.
I have a visual studio solution that uses multiple projects. I find a strange behavior with compiling/linking using VS2012 under debug mode. I have a project 'X', and it has a header file "A.h" contains
template <class T>
double Test( const T & in) //first function
{
std::cout<<"1\n";
return 0.0;
}
template <class T>
T Test( const T & in, const bool in) //second function
{
std::cout<<"2\n";
return T(0.0);
}
void dTest(dataType in)
{
Test(in)
}
void TTest(dataType in);
and "A.cpp"
#include "A.h"
void TTest(dataType in)
{
Test (in, true);
}
Then some where in the solution I call TTest and dTest.
It prints 1 and 2 as expected.
Then I change code to print 3 and 4 respectively;
and build, which leads to compilation of A.cpp.
However when I run it prints 3 and 2.
It I try to place a break point in the first function it reaches there.
However if I set break point in the second function, the debugger complains "break point will not be hit. Source code version is different".
I could not reproduce this behavior in "release" mode, yet. Doing a rebuild brings correct behavior. Why do I see this behavior? There is a single dll file created for each project. How can it have part from current code and part from previous code?. I am working with TFS systetm. Does this mean, VS keeps an intermediate file that is different from my current file?
Any insights/solution to the problem (apart from rebuild/clean) appreciated
Thanks
Visual Studio doesn't do a good job of tracking dependencies. See How do I make sure that when a .h file is modified, the .cc files including it are compiled automatically in a Release build using Visual Studio 2008?.
If you modify a .h file, the only safe method to make sure that the change takes effect is to rebuild all the projects in the solution.
PS
In my experience, the dependencies get picked up correctly in debug builds. The problem is only in release builds.
I am trying to create Unit Tests in Visual Studios 2012 using a Native Unit Test Project.
This is the test I have:
TEST_METHOD(CalculationsRoundTests)
{
int result = Calculations::Round(1.0);
Assert::AreEqual(1, result);
}
Exporting the Class:
#ifdef EXPORT_TEST_FUNCTIONS
#define MY_CALCULATIONS_EXPORT __declspec(dllexport)
#else
#define MY_CALCULATIONS_EXPORT
#endif
...
class CALCULATIONS_EXPORT Calculations {
...
public:
static int Round(const double& x);
The function itself:
int Calculations::Round(const double& x)
{
int temp;
if (floor(x) + 0.5 > x)
temp = floor(x);
else
temp = ceil(x);
return int(temp);
}
However, the test nearly always fails with error code c0000005 (Access Violation).
The test will fail the first time that x, or any other variable that may be declared in the function, is used.
I followed the instructions at Unresolved externals when compiling unit tests for Visual C++ 2012
This is a known bug. Unfortunately, Microsoft considers this as "Won't Fix".
In short, there are two workarounds:
Compile the actual project in release mode and the test project in debug mode.
Outsource all testable functions to a static library project.
I never figured out why the test would cause an access violation when it was run; however, I'm sure I had set something up wrong.
To remove this error, I changed the structure of my Visual Studio solution to have the majority of the code be in a static library (.lib) project which will contain the implementation of my program. By doing this, all of the classes and functions for my program in the project are automatically exported, so I don't need to use __declspec(dllexport).
Then, I created a small Win32 Console Application, which will create the .exe file for my program, that references the .lib project. The purpose of this project is to create the executable file for my program, so all it needed was a main that would call the start of my code in the .lib project.
After I did this, I was able to get the Native Unit Test project to work easily by just getting it to also reference the .lib project, and I haven't had any access errors since.