I have tried this code in a totally separate project, and it works fine (the only difference being that the project that is not working is being exported as a DLL). Here is the code:
RTATMATHLIB.CPP
#include "stdafx.h"
#include "RTATMATHLIB.h"
#include <math.h>
#include <vector>
#include <algorithm>
#include <stdexcept>
using namespace std;
double someFunc(double** Y, int length)
{
vector<double> myVector;
for(int i = 0; i < length; i++)
{
double value = (*Y)[i];
vector<double>::iterator it = find(myVector.begin(), myVector.end(), value);
if(it != myVector.end())
{
continue;
}
else
{
myVector.push_back(value);
}
}
return 0;
}
RTATMATHLIB.H
__declspec(dllexport) double someFunc(double** Y, int length);
ERRORS
Error 1 error LNK2019: unresolved external symbol __imp___CrtDbgReportW referenced in function "public: __thiscall std::_Vector_const_iterator<double,class std::allocator<double> >::_Vector_const_iterator<double,class std::allocator<double> >(double *,class std::_Container_base_secure const *)" (??0?$_Vector_const_iterator#NV?$allocator#N#std###std##QAE#PANPBV_Container_base_secure#1##Z) RTATMATHLIB.obj RTATMATHLIB
Error 2 fatal error LNK1120: 1 unresolved externals
And that's it. I am not sure why it works in the other project and not this one...
I found another forum post, where somebody seems to have reported the same exact problem that you are having. Please check to see if you have
_DEBUG
defined either in your project settings (under C/C++ -- Preprocessor) or somewhere in your code (or include files).
It looks as if std::vector thinks you are building a debug build, when you are in fact creating a release build.
I hope this helps.
The problem in my case was a Debug configuration with Runtime Library set to Multi-threaded DLL. The fix was to change it to Multi-threaded Debug DLL. The error is gone. Removing _DEBUG macro was also a kind of workaround, by I guess it's not a good idea because you end up with debug build linked to non-debug standard library.
The problem was I had _DEBUG defined in C/C++->Preprocessor. Changing it to NDEBUG solved the problem.
Worked for me with :
The problem in my case was a Debug configuration with Runtime Library set to Multi-threaded DLL. The fix was to change it to Multi-threaded Debug DLL
Related
Similar to LNK2005 Error in CLR Windows Form, yet this answer cannot explain what I've met.
My question is at the end of the description, thanks for the patience.
The project structure is as below (I simplify the situation to demonstrate the problem I met, which does not make any sense in real development):
Environment: Visual Studio 2019
Configuration: Debug/x86
OpenCV 420: I compile it to a dynamic library (.lib+.dll) myself because the x86 version is not provided officially.
Project2: pure C++, output type: lib
// ClassB.h
#pragma once
#include <opencv2/opencv.hpp>
class ClassB
{
public:
void FuncB();
};
// ClassB.cpp
#include "ClassB.h"
void ClassB::FuncB() {
cv::Mat mat;
}
Project3: C++ with /clr on, output type: dll for .NET Framework v4.6.1
// ClassC.h
#pragma once
#include <iostream>
#include <opencv2/opencv.hpp>
class __declspec(dllexport) ClassC
{
};
// ClassC.cpp
#include "ClassC.h"
Link against (the input libs order matters, will explain later)
opencv_world420d.lib (it's just an import library, at runtime use opencv_world420d.dll)
Project2.lib
And the compiler throws errors:
LNK2005 "public: __thiscall cv::MatSize::MatSize(int *)" (??0MatSize#cv##QAE#PAH#Z) already defined in opencv_world420d.lib(opencv_world420d.dll) Project3 (ClassB.obj) 1
LNK2005 "public: __thiscall cv::MatStep::MatStep(unsigned int)" (??0MatStep#cv##QAE#I#Z) already defined in opencv_world420d.lib(opencv_world420d.dll) Project3 (ClassB.obj) 1
After some digging, I suppose it is because there're some inline functions in mat.inl.hpp header file which is needed by class Mat and included byopencv.hpp(indirectly though), as below:
inline
MatStep::MatStep(size_t s)
{
p = buf; p[0] = s; p[1] = 0;
}
Maybe the compiler decided not to inline the functions, but indexed them into Project2.lib, to assure, I dump the two libs:
// Project2.lib
8B6 00000000 SECT109 notype () External | ??0MatSize#cv##QAE#PAH#Z (public: __thiscall cv::MatSize::MatSize(int *))
// opencv_world420d.lib
??0MatSize#cv##QAE#PAH#Z (public: __thiscall cv::MatSize::MatSize(int *))
As far as I know, SECT109 and External do mean that Project2.lib has complete definition of cv::MatSize::MatSize(int *), so do opencv_420world420d.lib
However, I explore 3 separate ways out to pass the compilation
Solution 1
swap the linking order to:
Project2.lib
opencv_world420d.lib
Solution 2
Turn the Project3 /clr off, make it a pure C++ project
Solution 3
MakeClassB::FuncBinline:
// ClassB.h
#pragma once
#include <opencv2/opencv.hpp>
class ClassB
{
public:
void FuncB() {
cv::Mat mat(100, 200, CV_8U);
}
};
// ClassB.cpp
#include "ClassB.h"
For solution1/2, I don't even touch Project2, so obviously ??0MatSize#cv##QAE#PAH#Z still exists in Project2.lib (so I don't understand how the compilation succeed).
For solution3, ??0MatSize#cv##QAE#PAH#Z disappears in Project2.lib (again I dumped the lib file and search the function name), so this does make sense to me.
In conclusion, my questions are:
Why solution 1 works, by just swapping the input libs order?
Why solution 2 works, by just switching off /clr for Project3 whose output target is dll?
OpenCV puts inline implementation in their hpp file, I wonder if it is a safe and good way to do so?
I am having a problem with Visual Studio 2019 CPPUnitTestFramework. I follow the instructions, but every time I get an error. I have looked for tutorials, but anything I get is for Visual Studio 2017 and it does not solve my problem.
I am writing a program that uses OOP in C++ and I want to make unit tests, since it is going to be a considerably long project. The problem that I am having is that the program is not compiling in the test module.
Consider that I have the code such that I have the header file:
//A.h
#pragma once
class A
{
private:
// One parameter.
int a;
public:
// Add function.
int add(int, int);
// Subtract function.
int subtract(int, int);
A();
};
with the proper source file:
// A.cpp
#include "A.h"
int a;
int A::add(int alpha, int beta)
{
return alpha + beta;
}
int A::subtract(int alpha, int beta)
{
return alpha - beta;
}
A::A()
{
a = 4;
}
The structure of the program looks something like this:
To make my Unit Test, I right click on the "Solution 'TestTestUnit'" label and choose new project, look for the unit test, add the unit test and attach the reference, such that I get a file structure such as the one below:
To perform the unit test I write the code:
// TestUnitForTestTestUnit.cpp
#include "pch.h"
#include "CppUnitTest.h"
#include "../TestTestUnit/A.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace TestUnitForTestTestUnit
{
TEST_CLASS(TestUnitForTestTestUnit)
{
public:
TEST_METHOD(TestMethod1)
{
A first;
Assert::AreEqual(first.add(3, 2), 5);
}
};
}
When I try to run a test, the Test Explorer does nothing and throws the message: Aborting test run due to build failures. Please see the build for more details.
I cannot find the mistake here. The program runs perfect, but when instantiating a new "A" object the test fails. I am stuck here, are there any suggestions? What am I doing wrong (besides developing in Windows)?
UPDATE:
I have followed the suggestion to remove the namespace, as suggested by #ChrisMM, so that the test file now reads:
// TestUnitForTestTestUnit.cpp
#include "pch.h"
#include "CppUnitTest.h"
#include "../TestTestUnit/A.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
TEST_CLASS(TestUnitForTestTestUnit)
{
public:
TEST_METHOD(TestMethod1)
{
A first;
Assert::AreEqual(first.add(3, 2), 5);
}
};
such that when I run the Test Explorer gives the same message:
with error message:
1>------ Build started: Project: TestUnitForTestTestUnit, Configuration: Debug Win32 ------
1> Creating library C:\Users\<user>\Desktop\CPlusPlus\TestTestUnit\Debug\TestUnitForTestTestUnit.lib and object C:\Users\<user>\Desktop\CPlusPlus\TestTestUnit\Debug\TestUnitForTestTestUnit.exp
1>TestUnitForTestTestUnit.obj : error LNK2019: unresolved external symbol "public: int __thiscall A::add(int,int)" (?add#A##QAEHHH#Z) referenced in function "public: void __thiscall TestUnitForTestTestUnit::TestMethod1(void)" (?TestMethod1#TestUnitForTestTestUnit##QAEXXZ)
1>TestUnitForTestTestUnit.obj : error LNK2019: unresolved external symbol "public: __thiscall A::A(void)" (??0A##QAE#XZ) referenced in function "public: void __thiscall TestUnitForTestTestUnit::TestMethod1(void)" (?TestMethod1#TestUnitForTestTestUnit##QAEXXZ)
1>C:\Users\<user>\Desktop\CPlusPlus\TestTestUnit\Debug\TestUnitForTestTestUnit.dll : fatal error LNK1120: 2 unresolved externals
1>Done building project "TestUnitForTestTestUnit.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========
Help would be appreciated.
You cannot put a test class inside a namespace. From the documentation
TEST_CLASS must be declared at namespace scope.
I suggest you to check if TestUnitForTestTestUnit has added Additional Dependencies. When I didn’t add it, the same problem as you occurred. After I added it, the program worked fine.
Right click TestUnitForTestTestUnit->Properties->C/C++->Linker->Input->Additional Dependencies-> add ..\TestTestUnit\Debug\*.obj
I normally work in c# and am out of my wits for this one . I used Walkthrough: Creating and Using a Dynamic Link Library (C++) to create a Dynamic Link Library.
I have defined two methods as shown below
DeveloperConsoleManager.h
#pragma once
#include "atlstr.h"
#ifdef DEVCONSOLEMANAGER_EXPORTS
#define DEVCONSOLEMANAGER_API __declspec(dllexport)
#else
#define DEVCONSOLEMANAGER_API __declspec(dllimport)
#endif
namespace DeveloperConsoleManager
{
class DeveloperConsoleLogic
{
public:
// Returns a + b
static DEVCONSOLEMANAGER_API double Add(double a, double b);
static DEVCONSOLEMANAGER_API bool CheckforValidFile(CString fileName);
};
}
DeveloperConsoleManager.cpp
// DeveloperConsoleManager.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "DeveloperConsoleManager.h"
namespace DeveloperConsoleManager
{
double DeveloperConsoleLogic::Add(double a, double b)
{
return a + b;
}
bool DeveloperConsoleLogic :: CheckforValidFile(CString fileName)
{
return false;
}
}
I use these methods in a .cpp file in a different project (type: Application (.exe)). When I Build the solution, there are following linker errors
Warning 1 warning C4273: 'DeveloperConsoleManager::DeveloperConsoleLogic::Add' : inconsistent dll linkage e:\md_69\developerconsolemanager\developerconsolemanager.cpp 10
Warning 2 warning C4273: 'DeveloperConsoleManager::DeveloperConsoleLogic::CheckforValidFile' : inconsistent dll linkage e:\md_69\developerconsolemanager\developerconsolemanager.cpp 16
Error 3 error LNK2028: unresolved token (0A0004F1) "public: static bool __cdecl DeveloperConsoleManager::DeveloperConsoleLogic::CheckforValidFile(class ATL::CStringT > >)" (?CheckforValidFile#DeveloperConsoleLogic#DeveloperConsoleManager##$$FSA_NV?$CStringT#_WV?$StrTraitMFC_DLL#_WV?$ChTraitsCRT#_W#ATL#####ATL###Z) referenced in function "public: void __thiscall CSaSsiConsoleUi::UploadSsiCheck(void)" (?UploadSsiCheck#CSaSsiConsoleUi##$$FQAEXXZ) E:\MD_69\DeveloperConsoleUI\SaSsiConsoleUI.obj
Error 4 error LNK2019: unresolved external symbol "public: static bool __cdecl DeveloperConsoleManager::DeveloperConsoleLogic::CheckforValidFile(class ATL::CStringT > >)" (?CheckforValidFile#DeveloperConsoleLogic#DeveloperConsoleManager##$$FSA_NV?$CStringT#_WV?$StrTraitMFC_DLL#_WV?$ChTraitsCRT#_W#ATL#####ATL###Z) referenced in function "public: void __thiscall CSaSsiConsoleUi::UploadSsiCheck(void)" (?UploadSsiCheck#CSaSsiConsoleUi##$$FQAEXXZ) E:\MD_69\DeveloperConsoleUI\SaSsiConsoleUI.obj
Error 5 error LNK1120: 2 unresolved externals E:\MD_69\Debug\DeveloperConsoleUi.exe
There is no linker error for the "Add" method.
I have already included "DeveloperConsoleManager.lib" in Linker -> Input -> Additional Dependencies. Please help me find out what exactly am I doing wrong.
I would be glad to add any additional information needed.
Thanks to #Igor Tandetnik and the awesome thing that is internet, I figured it out. I am adding it as an answer so that some one else might benefit.
The problem was with CString. The project in which the function was defined was a dynamic link library (dll) and the call was being made from an MFC application. Now, the issue was that, MFC uses for CString while the non-MFC dll uses .
CString in is defined as:
typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString;
while in is defined as:
typedef CStringT< TCHAR, StrTraitATL< TCHAR > > CString;
This, as you can clearly see is different. The workaround I used was using CAtlString instead of CString . However, please feel free to suggest any better way if you come across.
I have tried this code in a totally separate project, and it works fine (the only difference being that the project that is not working is being exported as a DLL). Here is the code:
RTATMATHLIB.CPP
#include "stdafx.h"
#include "RTATMATHLIB.h"
#include <math.h>
#include <vector>
#include <algorithm>
#include <stdexcept>
using namespace std;
double someFunc(double** Y, int length)
{
vector<double> myVector;
for(int i = 0; i < length; i++)
{
double value = (*Y)[i];
vector<double>::iterator it = find(myVector.begin(), myVector.end(), value);
if(it != myVector.end())
{
continue;
}
else
{
myVector.push_back(value);
}
}
return 0;
}
RTATMATHLIB.H
__declspec(dllexport) double someFunc(double** Y, int length);
ERRORS
Error 1 error LNK2019: unresolved external symbol __imp___CrtDbgReportW referenced in function "public: __thiscall std::_Vector_const_iterator<double,class std::allocator<double> >::_Vector_const_iterator<double,class std::allocator<double> >(double *,class std::_Container_base_secure const *)" (??0?$_Vector_const_iterator#NV?$allocator#N#std###std##QAE#PANPBV_Container_base_secure#1##Z) RTATMATHLIB.obj RTATMATHLIB
Error 2 fatal error LNK1120: 1 unresolved externals
And that's it. I am not sure why it works in the other project and not this one...
I found another forum post, where somebody seems to have reported the same exact problem that you are having. Please check to see if you have
_DEBUG
defined either in your project settings (under C/C++ -- Preprocessor) or somewhere in your code (or include files).
It looks as if std::vector thinks you are building a debug build, when you are in fact creating a release build.
I hope this helps.
The problem in my case was a Debug configuration with Runtime Library set to Multi-threaded DLL. The fix was to change it to Multi-threaded Debug DLL. The error is gone. Removing _DEBUG macro was also a kind of workaround, by I guess it's not a good idea because you end up with debug build linked to non-debug standard library.
The problem was I had _DEBUG defined in C/C++->Preprocessor. Changing it to NDEBUG solved the problem.
Worked for me with :
The problem in my case was a Debug configuration with Runtime Library set to Multi-threaded DLL. The fix was to change it to Multi-threaded Debug DLL
I have tried this code in a totally separate project, and it works fine (the only difference being that the project that is not working is being exported as a DLL). Here is the code:
RTATMATHLIB.CPP
#include "stdafx.h"
#include "RTATMATHLIB.h"
#include <math.h>
#include <vector>
#include <algorithm>
#include <stdexcept>
using namespace std;
double someFunc(double** Y, int length)
{
vector<double> myVector;
for(int i = 0; i < length; i++)
{
double value = (*Y)[i];
vector<double>::iterator it = find(myVector.begin(), myVector.end(), value);
if(it != myVector.end())
{
continue;
}
else
{
myVector.push_back(value);
}
}
return 0;
}
RTATMATHLIB.H
__declspec(dllexport) double someFunc(double** Y, int length);
ERRORS
Error 1 error LNK2019: unresolved external symbol __imp___CrtDbgReportW referenced in function "public: __thiscall std::_Vector_const_iterator<double,class std::allocator<double> >::_Vector_const_iterator<double,class std::allocator<double> >(double *,class std::_Container_base_secure const *)" (??0?$_Vector_const_iterator#NV?$allocator#N#std###std##QAE#PANPBV_Container_base_secure#1##Z) RTATMATHLIB.obj RTATMATHLIB
Error 2 fatal error LNK1120: 1 unresolved externals
And that's it. I am not sure why it works in the other project and not this one...
I found another forum post, where somebody seems to have reported the same exact problem that you are having. Please check to see if you have
_DEBUG
defined either in your project settings (under C/C++ -- Preprocessor) or somewhere in your code (or include files).
It looks as if std::vector thinks you are building a debug build, when you are in fact creating a release build.
I hope this helps.
The problem in my case was a Debug configuration with Runtime Library set to Multi-threaded DLL. The fix was to change it to Multi-threaded Debug DLL. The error is gone. Removing _DEBUG macro was also a kind of workaround, by I guess it's not a good idea because you end up with debug build linked to non-debug standard library.
The problem was I had _DEBUG defined in C/C++->Preprocessor. Changing it to NDEBUG solved the problem.
Worked for me with :
The problem in my case was a Debug configuration with Runtime Library set to Multi-threaded DLL. The fix was to change it to Multi-threaded Debug DLL