LNK2005 error in debug mode only - c++

Usually I eventually manage to sort out these LNK2005 (symbol already defined in object) errors but this one has me beat. I have a VS2010 solution containing several projects among them a project outputting an executable. This executable depends on libraries contained within the same solution thus I have added them into the "References" list for the executable project so that they get linked in automatically.
Now what happens when I try to build my executable (Server.exe) is that everything builds successfully when the release configuration is selected, but if I switch over to debug I get the following LNK2005 error:
error LNK2005: "public: class ACE_SOCK_Stream & __thiscall ACE_Svc_Handler<class ACE_SOCK_Stream,class ACE_NULL_SYNCH>::peer(void)const " (?peer#?$ACE_Svc_Handler#VACE_SOCK_Stream##VACE_NULL_SYNCH####QBEAAVACE_SOCK_Stream##XZ) already defined in Shell.obj network.lib(network.dll) Server (server\Server)
As can be seen in the error the projects use the ACE library.
I have had a look at ACE_Svc_Handler<class ACE_SOCK_Stream,class ACE_NULL_SYNCH> that is mentioned in the error and found out that one exported class in the network.dll inherits from it:
class DLL_API NetHandler : public ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH >
{
...
}
...and in the Server.exe there is also one class inheriting from it:
class Shell : public ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH >
{
...
}
The peer() method mentioned in the error is then used by both the NetHandler and Shell classes.
I am not sure if, and if so why, this would cause a LNK2005 error? What confuses me even more is that I only get the linker error in debug mode. I should also mention that the NetHandler class exported by network.dll is not used by the Server.exe, other projects that also depend on the network.dll do however.
Any ideas what could be causing this and how it can be solved? I am not sure where I should continue to investigate.
UPDATE: If I don't export the NetHandler class in my network.dll the linker error goes away, but I need to export that class.
UPDATE 2: I found this link in a different question about LNK2005 and although the link doesn't describe my scenario exactly I tried the proposed solution and I managed to get rid of the linker error if I place the following line before class Shell... in my Server.exe project:
extern template class __declspec(dllimport) ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH >;
So what does this line do exactly? Does it tell the Server project to not define ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > itself but instead import it from one of the linked in libraries?

Related

LNK2005 & LNK1169 error when use QMap between 2 dlls

I have an issue since 2days about an LNK2005 & LNK1169 error on MSVC 2015 (Qt 5.12.6)
My error is:
Core.lib(Core.dll) : error LNK2005: "public: __cdecl QMap<int,double>::~QMap<int,double>(void)" (??1?$QMap#HN##QEAA#XZ) already defined in xxx.obj
I have the error when i'm trying to compile a library (named AAA)
The library AAA use Core.dll and both use a 2nd lib named Common.dll. The type QMap<int,double> is used in each libraries.
When i'm looking xxx.obj (located in AAA), the only one usage i have of QMap<int,double>, is when i'm use a function that return a QMap and located in Core.dll
I have lot of function defined in Core and used in AAA but i never seen this error before.
I have check multiple things: trying to change the QMap with QVector, same type of error.
I don't have any "include cpp file"
I don't have the error when i'm using Clang or GCC to compile the project.
I don't have the error if i'm using a QMap<int,double>*, but i don't want to
I think it's an error related to the qmap template but i'm not sure
Do you have an idea? Thanks
Ps: i'v change the name of third lib (AAA) cause this is a code i use for my work and cannot share lot of things about it
So, i have fix my pb by replacing each usage of QMap<int, double> by another object located in a third library.
I have seen multiple definition of QMap<int, double> in the dlls by using Dependency Walker and that why the code counln't compile.
But I don't know if is a problem with the compiler (MSVC2015) or with my code.
I have used these website to help me:
https://forum.qt.io/topic/43408/error-lnk2005-when-deriving-from-qvariantmap
http://web.archive.org/web/20090323151858/https://mareq.com/2008/10/exporting-non-template-class-inherited.html

Error LNK2019 when building Tensorflow debug

I try make a debug build of the CPU version of the C++ API of Tensorflow 2.0 in Windows. The command I use for building is:
bazel build -c dbg --copt=/w34716 tensorflow:tensorflow.dll
But when I build this I get this error:
depth_space_ops.lo.lib(depthtospace_op.obj) : error LNK2019: unresolved external symbol "public: void __cdecl tensorflow::functor::DepthToSpaceOpFunctor<struct Eigen::GpuDevice,struct Eigen::half,1>::operator()(struct Eigen::GpuDevice const &,class Eigen::TensorMap<class Eigen::Tensor<struct Eigen::half const ,4,1,__int64>,16,struct Eigen::MakePointer>,int,class Eigen::TensorMap<class Eigen::Tensor<struct Eigen::half,4,1,__int64>,16,struct Eigen::MakePointer>)" (??R?$DepthToSpaceOpFunctor#UGpuDevice#Eigen##Uhalf#2#$00#functor#tensorflow##QEAAXAEBUGpuDevice#Eigen##V?$TensorMap#V?$Tensor#$$CBUhalf#Eigen##$03$00_J#Eigen##$0BA#UMakePointer#2##4#HV?$TensorMap#V?$Tensor#Uhalf#Eigen##$03$00_J#Eigen##$0BA#UMakePointer#2##4##Z) referenced in function "public: virtual void __cdecl tensorflow::DepthToSpaceOp<struct Eigen::ThreadPoolDevice,struct Eigen::half>::Compute(class tensorflow::OpKernelContext *)" (?Compute#?$DepthToSpaceOp#UThreadPoolDevice#Eigen##Uhalf#2##tensorflow##UEAAXPEAVOpKernelContext#2##Z)
The only thing I found regarding this issue was this GitHub issue, which wasn't solved.
Does anyone know how to solve this issue?
Facing the same necessity, I dug around in the code and actually found the source of the problem: It is contained in the following two if blocks: https://github.com/tensorflow/tensorflow/blob/v2.3.0/tensorflow/core/kernels/spacetodepth_op.cc#L129 and https://github.com/tensorflow/tensorflow/blob/v2.3.0/tensorflow/core/kernels/depthtospace_op.cc#L115.
If you are building a non-GPU version of the library in debug, it is sort of clear why the error happens: the if (std::is_same<Device, GPUDevice>::value) for the DepthToSpaceOp class, for example, parametrized with CPUDevice, would evaluate to if (false) during compile time. With any optimizations enabled, the code in the if-clause (which explicitly triggers DepthToSpaceOpFunctor with a template parameter GPUDevice - exactly the missing symbols you are getting) would not be compiled at all, and therefore not need to be linked.
In the debug build, it is still likely compiled, even though it is clear that it will never be executed. Then the linker tries to find the operator() for the DepthToSpaceOpFunctor template-parametrized with GPUDevice, and fails to do so.
A quick-and-dirty way to fix this is to comment out the entire if-clauses (if you are building a CPU-only dll) in both files mentioned above.
A more elegant solution is to avoid these linker errors via template specialization by changing the explicit references to GPUDevice to Device, since those will be in the code that is executed only when Device is GPUDevice. I will soon add a pull request to a similar issue I raised on github, hopefully, after a bit more testing.
Update: The pull request is submitted, you can find the code changes to fix this particular set of linker errors here: https://github.com/tensorflow/tensorflow/pull/42307/files#
For a GPU debug dll - I am not sure why these errors would still be there, but there are yet other linking errors in this case anyway ;)

CGAL Skeletonization compile errors

I'm new to C++ and CGAL, previously I worked mainly with C#.
I installed CGAL as described on https://www.cgal.org/download/windows.html and all steps finished successfully.
Then I looked to a CGAL 'Hello world' (https://doc.cgal.org/latest/Manual/Kernel_23_2points_and_segment_8cpp-example.html); here I had no problem also; all the code was compiled and run propertly.
But when I tried with more complex things I got a strange issue. For example I tried to compile Skeletonization (https://doc.cgal.org/latest/Surface_mesh_skeletonization/Surface_mesh_skeletonization_2simple_mcfskel_example_8cpp-example.html);
here I got a number of errors like these:
C2039 ''extract_mean_curvature_flow_skeleton'': is not a member of ''CGAL''
C2039 ''Matrix'': is not a member of ''CGAL::Default''
C2039 ''Vector'': is not a member of ''CGAL::Default''
As far as I understand it the #include lines processed without errors, all needed headers exist.
I tried to search the answer and found this: http://cgal-discuss.949826.n4.nabble.com/Problem-on-Surface-mesh-deformation-td4661042.html
Unfortunately I don't be sure my case is similar and I don't know what exactly do the line #define CGAL_EIGEN3_ENABLED as recommended there.
In any case I tried to add it and got the same errors as previous if this #define inserted after #include ; in different case arise a lot of errors like this:
LNK2019 unresolved external symbol __imp___gmpq_add referenced in function "class CGAL::Gmpq __cdecl CGAL::operator+(class CGAL::Gmpq const &,class CGAL::Gmpq const &)" (??HCGAL##YA?AVGmpq#0#AEBV10#0#Z)
I work with VS 2017, in Additional library directories I added:
$(CGAL_DIR)/lib/Debug;$(CGAL_DIR)/lib
in Additional include directories:
$(CGAL_ROOT)\include;$(CGAL_ROOT)\auxiliary\gmp\include;
$(CGAL_DIR)\include;$(BOOST_INCLUDEDIR)
maybe some needed libraries or include directories are missing here?
All the components (CGAL, boost, QT) installed in 64 bits versions as well as test project.
UPD: The question is solved!
The answer was extremely simple (please note I'm new in C++):
1. I loaded and unzip EIGEN (it need not to install); for convenience I create also EIGEN_DIR variable;
2. I added to Additional Include Directories: $(EIGEN_DIR);
3. I added before #include statements #define CGAL_EIGEN3_ENABLED;
4. I added to Additional Dependencies such libs:
$(CGAL_ROOT)\auxiliary\gmp\lib\libmpfr-4.lib
$(CGAL_ROOT)\auxiliary\gmp\lib\libgmp-10.lib
and it start to work!

Getting "error LNK2001: unresolved external symbol _gnutls_free" when using GnuTLS 3.1.6 from Visual Studio 2012

I am attempting to build a project in Visual Studio 2012 that uses GnuTLS. I downloaded the latest official Windows build from the website, and created a link library by running lib /def:libgnutls-28.def in the bin directory form a Visual Studio command prompt.
After adding a typedef long ssize_t, the code compiles fine, but linking fails with the following error:
source_file.obj : error LNK2001: unresolved external symbol _gnutls_free
C:\Path\to\executable.exe : fatal error LNK1120: 1 unresolved externals
I am calling gnutls_free to free some memory allocated and returned by the library. If I remove the call to gnutls_free, the project links successfully. Given that gnutls_free is just a global variable (containing a function pointer) exported by the library, I'm not sure why accessing it results in an unresolved reference to a different symbol. I have verified that gnutls_free is not #defineed to anything.
As a test, I tried doing gnutls_free_function test = gnutls_free; which also resulting in the link error. Running grep -w -r _gnutls_free . on the GnuTLS source code returns nothing, so I am at a loss.
Any ideas for getting this working would be greatly appreciated.
EDIT:
Adding __declspec(dllimport) to the declaration of gnutls_free in gnutls.h allows the link to succeed. Is there any way to accomplish this without maintaining a custom version of the header file?
There doesn't seem to be a way to have the linker or import library automatically dereference the IAT's pointer to the data item the same way that is done for functions (via a small trampoline function that is statically linked into the module importing the function). The __declspec(dllimport) attribute tells that compiler that this dereferencing needs to be done so it can insert code to perform the dereferencing of the IAT pointer implicitly. This allows exported data to be accessed and for functions allows the compiler to call the imported function via an indirect call through the IAT pointer rather than by calling the trampoline function.
See a couple of Raymond Chen's articles about dllimport for a good explanation of what goes on for function calls (he didn't discuss importing data, unfortunately):
Calling an imported function, the naive way
How a less naive compiler calls an imported function
The MS linker or import library doesn't have a mechanism to help the compiler get imported data in a 'naive' way - the compiler needs the the __delcspec(dllimport) hint that an extra dereference through the IAT is needed. Anyway, the point of all this is that it seems there's no way to import data except by using the __declspec(dllimport) attribute.
If you want to avoid modifying the gnutls distribution (which I can understand), here's one rather imperfect workaround:
You can create a small object file that contains nothing but a simple wrapper for gnutls_free(); since gnutls_free() has an interface with no real dependencies, you can have the necessary declarations 'hardcoded' instead of including gnutls.h:
typedef void (*gnutls_free_function) (void *);
__declspec(dllimport) extern gnutls_free_function gnutls_free;
void xgnutls_free(void* p)
{
gnutls_free(p);
}
Have your code call xgnutls_free() instead of gnutls_free().
Not a great solution - it requires your code to call a wrapper (so it's particularly not great if you'll be incorporating 3rd party code that might depend on gnutls_free()), but it might be good enough.

Unresolved Externals Nightmare

Hello industry veterans,
I am a junior in college embarking on my first summer programming internship, and I am in way over my head. The company I'm working for has purchased a colossal application from another company that has slowly been expanding and modifying it since the early 90's. The solution contains over 200,000 lines of code which are spread across more than 300 files. The entire solution has purportedly been written to ANSI-C++ standards. The code is almost entirely undocumented, and most of it looks like hieroglyphs to me. Ultimately, my job is to port this code to embedded Linux. At the moment, my job is simply to get it compiling using Visual Studio 2008 on Windows XP.
Today, I'm running into linker errors such as this one:
libcmtd.lib(sprintf.obj) : error LNK2005: _sprintf already defined in msvcrtd.lib(MSVCR90D.dll)
My understanding is that this often happens when different projects within a solution are compiled using different runtime libraries. There are 6 projects in my solution. 4 of them were set to compile using the multi-threaded debug DLL runtime library (/MDd), one of them was set to compile using the multi-threaded debug library (/MTd), and one of them was set to compile using the multi-threaded dll runtime library (/MD). The first thing I tried after receiving this error message was to change the /MTd and /MD switches to /MDd so that everything would have compiled with the same runtime libraries. Unfortunately, this led to the following error in afx.h:
fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]
After some digging around, I discovered that it had already told me what I needed to do. I went ahead and changed the "Use of MFC" option under Project Properties->Configuration Properties->General to "Use MFC in a Shared DLL". At this point I started receiving dozens of unresolved external errors such as these:
dataPropertySheet.obj : error LNK2019: unresolved external symbol "public: __thiscall CResizableSheet::CResizableSheet(unsigned short const *,class CWnd *,unsigned int)" (??0CResizableSheet##QAE#PBGPAVCWnd##I#Z) referenced in function "public: __thiscall CdataPropertySheet::CdataPropertySheet(unsigned short const *,class CWnd *,unsigned int)" (??0CdataPropertySheet##QAE#PBGPAVCWnd##I#Z)
ResizableLib.lib(ResizablePage.obj) : error LNK2001: unresolved external symbol "public: virtual int __thiscall CWnd::Create(char const *,char const *,unsigned long,struct tagRECT const &,class CWnd *,unsigned int,struct CCreateContext *)" (?Create#CWnd##UAEHPBD0KABUtagRECT##PAV1#IPAUCCreateContext###Z)
After reading through the MSDN pages on LNK2001 and LNK2019, I've realized I have no idea what's going on. These are not the sort of issues they've taught us how to deal with in school. I know my data structures, and that's about it. How I ended up where I am now is beyond me!
From my limited knowledge, it seems that the various debug and release versions of these modules are all tangled up in a web of preprocessor directives and #includes. There are a number of nested #ifdef checks and #define statements done in nearly every header and source file throughout the solution for environment variables, file names, macros, and possibly more. By making even small changes to my compiler settings, I seem to be redirecting large parts of the program to different libraries which have very different function definitions. This is my vague conceptual understanding of what's going on.
I feel as though I'm going to need a better understanding of how this code works before I stand any chance of troubleshooting these compiler errors. To that end, I've been trying to step through many of the files line by line to see where they lead, what objects and variables are in scope, and so on. Unfortunately, this doesn't get me very far, because every call to an external function is ambiguous, and I have no way of seeing through the preprocessor mess to know which version of any given function is supposed to be called.
I was looking around for magic solutions to map out the program and try to make sense of it. I tried one called Doxygen, but either I don't know how to use it properly or it's getting just as confused by the preprocessor stuff as I am.
My question is this:
What are my remaining options?
At this point it's a toss up between:
a.) Switch majors
b.) Jump off a bridge
Neither of these choices are going to help me better understand this code base and get it compiling. Does anybody have any better ideas? Similar experiences? Sage wisdom to share?
Thanks a ton,
-Alex
It appears you're using the CResizableSheet and CResizeablePage from CodeProject. If you're using the compiled static lib from that page, you could try downloading the source and compiling that with the matching /MDd setting and using the .lib it outputs in the linker input section of your project. I'd also suggest doing a clean all (go to build->batch build->select all then click clean) and then try building again to make sure everything is up to date.
I hear nursing is a great program ...
At the risk of being pedantic, what you are fighting with are linker errors, not compiler errors. My basic approach to this would be to create a new solution, and start adding projects one at a time, getting each one to build in turn.
I would also seriously consider trying to standardize the settings of each project as much as possible. The easiest way to do this is to create empty projects in your new solution, and copy the existing code into them.
To start with you should assume the following settings (related to MFC):
Debug: Use MFC in a shared DLL, /MDd
Release: Use MFC in a shared DLL, /MD
MDd and MD are the same mode, but one links against debug libraries with extra information for debugging.
Then all you can do is work on one project at a time. Note that if you create a new solution as suggested, you'll need to rebuild the dependency tree between projects. (Right click on a project and choose 'Dependencies', you'll see what I mean.)
When you run into problems doing this, you should make friends with a senior developer at your workplace =).
Compile everything with the same runtime libraries. End of story.