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 want to buy license for QR codes read and generating from Leadtools but first I want to try their demo tools. I'm using MSVC 2013 x64 compiler. I think I did everything as follows in documentation:
Copied all dll's to my project directory (where build and release folder are located)
Copied Include and Lib folders to my project directory and add this lines to .pro file.
LIBS += -L$$PWD/Lib/CDLLVC12/x64/ -lLtkrn_x
INCLUDEPATH += $$PWD/Include
PRE_TARGETDEPS += $$PWD/Bin/CDLLVC12/x64/Ltkrnx.dll
include and #define LTV19_CONFIG, here is my code:
#define LTV19_CONFIG
#include <iostream>
#include <Ltkrn.h>
#include <ClassLib/LtWrappr.h>
using namespace std;
int main( ){
if( LT_KRN == LBase::LoadLibraries( LT_KRN, LT_DLGKRN))
cout << "success" << endl;
L_TCHAR licenseFile[] = L"d:\\temp\\TestLic.lic";
L_TCHAR key[] = L"xyz123abc";
LSettings::SetLicenseFile( licenseFile, key);
return 0;
}
Ask leadtools support, but they don't have much experience with working with QT...
When I tries to build application I get following errors:
LNK2019: unresolved external symbol "__declspec(dllimport) public: static unsigned int __cdecl LBase::LoadLibraries(unsigned int,unsigned int)" (__imp_?LoadLibraries#LBase##SAIII#Z) referenced in function main
LNK2019: unresolved external symbol "__declspec(dllimport) public: static int __cdecl LSettings::SetLicenseFile(wchar_t *,wchar_t *)" (__imp_?SetLicenseFile#LSettings##SAHPEA_W0#Z) referenced in function main
For following methods documentation says that I only need one dll/lib package (ltkrn). How to fix it? Still I don't get differences between static and dynamic linkage and this could be the problem.
If your linker accepted the 64-bit Ltkrn_x.lib, this suggests the problem is related to how you're using LEADTOOLS and not to QT. That's why I'm posting this as suggested reply instead of a note.
When programming using LEADTOOLS with C++, you normally use one of 2 sets of headers and LIBs:
Either include L_Bitmap.H (or a bunch of headers that includes LtKrn.H) and use the Ltkrn_x, Ltfil_x, etc. set of LIB files.
Or include ClassLib\LtWrappr.h and use only one LIB file, which in your case is Ltwvc_x.lib
Although in both cases you would be using many of the same DLL files such as Ltfilx.dll and Ltkrnx.dll, the reason you don't need their LIB files when using LtWrapper is that the ClassLibrary performs late (on demand) loading of these DLLs at run-time instead of referencing their LIB files at link time.
That's also why you need to call LBase::LoadLibraries() and specify the DLLs you need before your code uses these DLLs.
So to summarize, please try this:
Remove #include "Ltkrn.h"
Remove the linker reference to Ltkrn_x.lib (although you'll need the DLL)
Keep #include "ClassLib/LtWrappr.h"
Add a linker reference to Ltwvc_x.lib
I am currently trying integrate the library Qt in my C++ project. First I thought I could use it like any other library. I downloaded it, added the include path and libs to my VS project and tried a small sample of code that just creates a simple window with a text edit and a button. This worked and the small user interface was displayed.
Now I started to try implementing a class derived from a QWidget and realised, that it might not be that simple. The class I tried creating looked like this:
#include <QtWidgets\qstylepainter.h>
#include <QtWidgets\qwidget.h>
class MapRenderer : public QWidget{
Q_OBJECT
public:
MapRenderer(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent* event);
};
And the corresponding cpp file:
MapRenderer::MapRenderer(QWidget *parent) : QWidget(parent){
}
void MapRenderer::paintEvent(QPaintEvent *event){
QPainter p(this);
p.setPen(QPen(Qt::black, 3));
p.drawPoint(QPointF(10, 20));
}
Now as I tried compiling this I started getting linker three linker errors that looked like this:
error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __cdecl MapRenderer::metaObject(void)const " (?metaObject#MapRenderer##UEBAPEBUQMetaObject##XZ) G:\Documents\C++ Projects\HistoricalBorders\MapRenderer.obj
error LNK2001: unresolved external symbol "public: virtual void * __cdecl MapRenderer::qt_metacast(char const *)" (?qt_metacast#MapRenderer##UEAAPEAXPEBD#Z)
error LNK2001: unresolved external symbol "public: virtual int __cdecl MapRenderer::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall#MapRenderer##UEAAHW4Call#QMetaObject##HPEAPEAX#Z)
So I had a look around on the internet and found out that Qt apparently requires a far more complicated build process than a 'normal' c++ project with 'normal' libraries. I read of qmake and a Visual Studio Qt Add-In that can be used to create Qt-Projects in Visual Studio.
So I gave it a try and installed the Visual Studio Add-In and specified my Qt-version's root directory in its settings. Afterwards my project still wouldn't compile, but the only error message then was:
error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'
Now I don't really get this, because my Qt library is 64bit and my project configuration also is 64bit as well as all the other libraries I am using. Furthermore, before installing the add-in I didn't have this problem. I have to say, my project is a 'normal' Visual Studio C++ console application. I saw that since I installed the VS Add-in it is also possible to choose 'Qt-console application' when creating a new project in Visual Studio. I also gave this a try but it didn't even compile after creating it. I also don't really know what the difference of a "Qt-project" to a normal VS-project is, except that the Qt libraries are included by default.
The other thing I have to mention is that I am using cmake to create my VS project file because I use version control (mercurial) and multiple people shall work on the project.
At the moment I am totally confused on how to get this library to work.
Now what is my question? Honestly, I don't really know. What I'm asking myself is:
Where does the architecture mismatch linker error come from?
Can I create a normal VS console application and get it to work with Qt?
What's the difference of a 'Qt-console application" to a normal VS project?
Is it possible to generate a Qt-compatible VS project with cmake?
EDIT: Now I uninstalled the Add-In again, reinstalled it but am now getting the old linker errors again (no longer the architecture mismatch). I have no idea why.
EDIT: Ok, some clarification. Yes, I want to use cmake. I also already have a cmakelists.txt and a findQt.cmake that I wrote myself and that asks you for your Qt root directory and then adds the necessary include paths and library paths to the project. This also works so far. E.g. the following code compiles without problems and shows an interface:
QApplication app(argc, argv);
QTextEdit *textEdit = new QTextEdit;
QPushButton *quitButton = new QPushButton("&Quit");
QObject::connect(quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(textEdit);
layout->addWidget(quitButton);
QWidget window;
window.setLayout(layout);
window.show();
app.exec();
Now if I try to create a class as shown above (the MapRenderer) I get the linker errors also shown above. Now I thought I am doing something wrong. My only question is what. From your comment, drescherjm, I see that I problably missed the moc-step (sorry but I have no idea what exactly that is).
If you have Qt project file (.pro) (or can get it somehow), you can run
cd <pro_folder>
qmake -tp vc
to (re-)generate Visual Studio project file with Qt build process properly set up, including
moc (meta object compiler; that's what you are missing now),
uic (processing designer's files)
rcc (resource compiler).
All generated files will be compiled and linked properly.
You don't even need AddIn for that.
I'm facing a weird issue here. I have my VS2012 project all set up, working properly. But when i tried the simple task of adding a method to one of my classes, it won't link correctly, i get
error LNK2019: unresolved external symbol "public: void __thiscall Camera::calcularDirecao(class GLFWwindow *)" (?calcularDirecao#Camera##QAEXPAVGLFWwindow###Z)
Here's my Camera class:
class Camera {
public:
Camera() { ... inline constructor ... }
~Camera() {}
... other methods ( which link fine ) ...
void calcularDirecao(GLFWwindow *);
};
And in my implementation file i have
void Camera::calcularDirecao(GLFWwindow *janela) {
... code ...
}
... other methods ...
I already tried rebuilding and all, with no success. Thanks in advance.
Recreate your project from scratch, check if it works or not. After that compare your vcxproj files. They are text files. Any text compare tool will work. Their difference may tell a lot.
Also try to view your source file in a hex editor. Look for any non ASCII symbols in your troubled method and around. Such symbols might be not displayed in the IDE viewer but still may confuse the compiler.
I doubt that your GLFWwindow definition is getting overridden by some other file included in your .cpp.
I have a Visual studio 2005 solution that has two projects. One is a static library and the other is a executable used to test the features in the static library. The static library uses MFC. I got the following errors when I built the solution.
uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2#YAPAXI#Z) already defined in LIBCMTD.lib(new.obj)
uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (?? 3#YAXPAX#Z) already defined in LIBCMTD.lib(dbgdel.obj)
uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new[](unsigned int)" (??_U#YAPAXI#Z) already defined in libcpmtd.lib(newaop.obj)
uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete[](void *)" (??_V#YAXPAX#Z) already defined in LIBCMTD.lib(delete2.obj)
I do not know how to overcome this. Can some one please explain why this error is occuring. Any explanation that gives an overview of .lib files linkage will be highly appreciated.
The CRT libraries use weak external linkage for the new, delete, and DllMain functions. The MFC libraries also contain new, delete, and DllMain functions. These functions require the MFC libraries to be linked before the CRT library is linked.
http://support.microsoft.com/kb/148652
Solution based on VS2005 (Replace Nafxcwd.lib with Uafxcwd.lib for ~VS2013)
go to project>properties>configuration properties>linker>input
add to "Additional dependency" -> Nafxcwd.lib Libcmtd.lib
add to "ignore specific library" -> Nafxcwd.lib;Libcmtd.lib
order of libraries is important( Nafxcwd.lib;Libcmtd.lib).
One thing to try is to make sure you have:
#include "stdafx.h"
as the first line in your .cpp files. I'm sure that's not the answer in all cases, but it made the identical error go away in my case.
I meet this problem in a MFC solution of Visual Studio 2010, while changing Use MFC in a Shared DLL into Use MFC in a Static Library in Project -> Properties -> Configuration Properties -> General.
I solve the problem by the following ways, please locate Project -> Properties -> Configuration Properties -> Linker -> Input at first.
In Debug mode:
Add uafxcwd.lib;Libcmtd.lib in Additional Dependencies.
Add uafxcwd.lib;Libcmtd.lib in Ignore Specific Default Libraries.
In Release mode:
Add uafxcw.lib;Libcmt.lib in Additional Dependencies.
Add uafxcw.lib;Libcmt.lib in Ignore Specific Default Libraries.
Notice:
Don't miss the ; between the two .lib files.
A suffix -d must be added in the files in Debug mode.
be sure that you have #include <afx.h> in "stdafx.h" BEFORE other includes like #include <string>
in config linker input
In additional dependicies put uafxcw.lib;LIBCMT.lib
In Ignore specific put put uafxcw.lib;LIBCMT.lib
Make sure the C++ runtime library that you are linking with is the same on your static library as well as your executable. Check your project properties C/C++->Code generation->runtime library settings.
Typo. One stupid way you got that is instead of include the header, you inlucde the cpp.
e.g.
#include <myclass.cpp> //should be #include <myClass.h>
First, libcmtd.lib is for a debug version and libcmt.lib is for production. Double-check that you're not including both. One place to check is the "Command Line" section of the Configuration Properties/Linker project properties.
If you go to the properties for the project, and open up the Configuration Properties/Linker/Input section, you can "Ingore Specific Library"...try listing libcmtd.lib in that field.
For me, I have a static library compiled with _CRTDBG_MAP_ALLOC, and the application not compiled with _CRTDBG_MAP_ALLOC, I was receiving then LNK2005. I've changed the application to compile with _CRTDBG_MAP_ALLOC, and the LNK2005 disappear.
Got rid of the problem
uafxcwd.lib(afxmem.obj) : warning LNK4006: "void * __cdecl operator new(unsigned __int64)"
In additional dependicies put uafxcw.lib.
In Ignore specific put put uafxcw.lib.
I had created two fresh projects with VS2017, one was working the other not, so I compared what was the difference. The one working was created with File > New Project > Visual C++ > MFC/ATL > MFC Application the one not working was created with File > New Project > Visual C++ > Windows Desktop > Windows Desktop Wizardthen adding MFC. In both cases I was using MFC as static lib. I had figured out two fixes. But before that we have to add imports because the second project had NONE!
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
Now either of the two fixes worked for me:
Project > Properties > Configuration Properties > General > Use of MFC set it to use in a Shared DLL, this should also automatically set C/C++ > Code Generation > Runtime Library to Multi-threaded debug dll /MDd make sure it indeed did that.
Try compile now, for me it worked.
I noticed the working project had some imports in stdafx.h, I copied them into pch.h in the other project, it worked.(Keeping the properties unchanged, so static lib was used). The code copied was this:
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
// turns off MFC's hiding of some common and often safely ignored warning messages
#define _AFX_ALL_WARNINGS
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
The other solutions changing Linker settings I tried them but they did not work.
I would appreciate if somebody knows why my solution works, it is weird, why including those headers in pch.h solves a linker issue whereas including those same headers anywhere else triggers that error??
Check the manifest file of both projects, make sure that they are linking the same version of the standard library. Most likely they are not, check the properties->code generation->standard library linking.
I also had a similar problem. The link given by Donnie explains the the reason. The solution was to look at the error messages and then removing those libs involved and adding those libs in the order of MFC libs first and then CRT libs.
The way to do that in vs2008 is given by ali.
I will also add that if you have replaced the new/delete operators (and if so, please do the array and the scalar both), you may need to tag them as __forceinline so that the obj doesn't collide with the lib.
For example, I did these to force aligned allocations and had the same trouble until I did that:
__forceinline void * operator new(size_t size)
{
return _aligned_malloc(size, 16);
}
__forceinline void operator delete(void* ptr)
{
_aligned_free(ptr);
}
__forceinline void * operator new [](size_t size)
{
return _aligned_malloc(size, 16);
}
__forceinline void operator delete [](void* ptr)
{
_aligned_free(ptr);
}
A header file declared and defined a variable. Possible solutions include:
Declare the variable in .h: extern BOOL MyBool; and then assign to it in a .c or .cpp file: BOOL MyBool = FALSE;.
Declare the variable static.
Declare the variable selectany.
https://msdn.microsoft.com/en-us/library/72zdcz6f.aspx
For me the problem was solved by changing
Project -> Properties -> Configuration Properties -> General: Use of
MFC = Use MFC in a Shared DLL
Before it was set to "Use Standard Windows Libraries"
Additionally I had to set the /MD option under
Project -> Properties -> C/C++ -> Code Generation : Runtime Library =
Multi-threaded DLL (/MD)
Another possible cause that I ran across while searching for this answer:
I accidentally left an #include "StdAfx.h" line at the top of a .cpp file that I moved from the application (which uses precompiled headers) into a shared static library (which doesn't use precompiled headers).
Got errors after applying Cipher Saw's solution to vs2015
1>afxnmcdd.lib(wincore2.obj) : error LNK2005: "void __stdcall DDX_Control(class CDataExchange *,int,class CWnd &)" (?DDX_Control##YGXPAVCDataExchange##HAAVCWnd###Z) already defined in uafxcwd.lib(wincore2.obj)
1>afxnmcdd.lib(wincore2.obj) : error LNK2005: "public: int __thiscall CWnd::ExecuteDlgInit(void *)" (?ExecuteDlgInit#CWnd##QAEHPAX#Z) already defined in uafxcwd.lib(wincore2.obj)
1>afxnmcdd.lib(wincore2.obj) : error LNK2005: "public: void __thiscall CMFCDynamicLayout::GetHostWndRect(class CRect &)const " (?GetHostWndRect#CMFCDynamicLayout##QBEXAAVCRect###Z) already defined in uafxcwd.lib(wincore2.obj)
1>afxnmcdd.lib(afxctrlcontainer2.obj) : error LNK2005: "void __cdecl AfxRegisterMFCCtrlClasses(void)" (?AfxRegisterMFCCtrlClasses##YAXXZ) already defined in uafxcwd.lib(afxctrlcontainer2.obj)
1>afxnmcdd.lib(afxctrlcontainer2.obj) : error LNK2005: "protected: void __thiscall CMFCControlContainer::PreUnsubclassControl(class CWnd *)" (?PreUnsubclassControl#CMFCControlContainer##IAEXPAVCWnd###Z) already defined in uafxcwd.lib(afxctrlcontainer2.obj)
1>afxnmcdd.lib(afxctrlcontainer2.obj) : error LNK2005: "public: int __thiscall CMFCControlContainer::SubclassDlgControls(void)" (?SubclassDlgControls#CMFCControlContainer##QAEHXZ) already defined in uafxcwd.lib(afxctrlcontainer2.obj)
Was able to fix them by changing libs list from uafxcw.lib;Libcmt.lib to afxnmcdd.lib;uafxcwd.lib;Libcmtd.lib (debug unicode build)