Question

Allow me to preface this question with 2 comments:
1) I'm a C# developer, so I don't have much practice dealing with linker errors in C++ and some standard C++ syntax is a bit unfamiliar to me. I suspect this will be an easy question to the C++ gurus out there.
2) I'm not sure how to ask this question in a way that will be relevant to the masses but I'm open to suggestions/corrections from the community. The problem with lnk2019 errors is that it seems pretty individualized as to what the problem actually is. MSDN has an article that deals with the error generally and Stack Overflow already has a slew of questions with that tag and yet I still can't seem to solve my problem.

On to the details...
I was given an old (VS2005) C++ solution with 42 projects and was asked to try and get it to build. After doing quite a bit of twiddling, I've gotten it down to just 3 projects that won't build. I'd like to focus on just one of them because I think if we can figure that one out, I can do the same things to the other 2 projects to fix them.

Let's start with the error. As you can see, the project in question is named "HttpWire".

Deleting intermediate and output files for project 'Http Wire', configuration 'Release|x64'
Compiling...
HttpWire.cpp
Compiling resources...
Linking...
Creating library Release\AMD64\HttpWire.lib and object Release\AMD64\HttpWire.exp
HttpWire.obj : error LNK2019: unresolved external symbol "public: __cdecl THttpWire::THttpWire(char const *)" (??0THttpWire@@QEAA@PEBD@Z) referenced in function CreateConnectionWire Release\AMD64\HttpWire.dll : fatal error LNK1120: 1 unresolved externals

Looks like the linker is upset because the function "CreateConnectionWire" is calling "THttpWire" but for some reason the linker is unable to find it. There is only 1 .cpp file in the project (HttpWire.cpp) and here it is:

#include "THttpWire.h"

BOOL WINAPI DllMain(HINSTANCE hDllInst, DWORD reason, LPVOID reserved)
{
    return TRUE;
}

__declspec(dllexport) TConnectionWire *CreateConnectionWire(LPCTSTR connectionString)
{
    return new THttpWire(connectionString);
}

__declspec(dllexport) void DeleteConnectionWire(TConnectionWire *connectionWire)
{
    delete connectionWire;
}

The #include file, "THttpWire.h" lives in another project called "AirTime Core". It includes several other things and then has the following:

class THttpWire : public TConnectionWire
{
public:
    THttpWire(LPCTSTR connectionString);
    virtual ~THttpWire();

... (lots of other stuff) ...
}

And then, finally, we have THttpWire.cpp:

#include "THttpWire.h"
...
THttpWire::THttpWire(LPCTSTR connectionString) :
TConnectionWire(connectionString),
hWinHttp(NULL), hSession(NULL), hRequest(NULL),
opTimedOut(FALSE), asyncError(0),
headers(NULL), headersOffset(0), headersLength(0),
availData(0)
{
    requestSent = new TSyncEvent(TRUE);
    updateToString();
}

This syntax is a bit weird to me... what are we doing here? I mean, I realize this is a constructor, and since THttpWIre appears to inherit from TConnectionWire (according to the .h), then the ":TConnectionWire(connectionString)" makes sense (I'm assuming this is like C# appending ": base()" to constructors of objects that inherit from other objects), but then what is all the other stuff between that and the opening brace (note that TConnectionWire does not appear to inherit from anything else)?

SO...
After doing some searching on MSDN and SO, I've learned the following (please correct me if I'm wrong)

  1. CreateConnectionWire is prefaced by __declspec(dllexport) which simply makes it available to other projects consuming this .dll (as discussed here)
  2. LPCTSTR is a const char* (see MSDN). Note that my projects are set with "Treat wchar_t as Built-in Type: No (/Zc:wchar_t-)" in the property pages. (see the bottom of this article and also this article)

Right now, my primary suspicion is with LPCTSTR. Perhaps it is not defined the same in both projects, which would yield different method signatures... but I don't know how to check for this or fix it if that is the case. Or, perhaps the "/Zc:wchar_t-" thing is affecting it adversely?
My next suspicion is that there is something in the string of methods listed in the constructor (with the syntax that I don't understand) that is causing some sort of problem and making the "THttpWire" constructor not available, generally.
What do you think? I'd be happy to share any other bits that you think would be useful.


Other information that may or may not be helpful (I'll let you decide)

  1. When I first started with this project, there were several .lib and .h files missing and I've had to go around trying to find them (examples were opends60.lib, mssoap30.lib, WinLUA.h, etc.). It is quite possible I don't have the same version the solution was originally built against.
  2. The projects were all built with "_WIN32_WINNT=0x0400" defined, which appears to mean it was meant to be built against the Windows 2000 SDK (see MSDN). I found something that I thought was the Win 2000 SDK (the oldest one on here, but when I link to that, I get many more errors. Instead, I'm linking to the SDK version 6.1. HOWEVER, this causes WinHttp not to compile because "SOCKADDR_STORAGE" isn't defined for anything "_WIN32_WINNT<0x0501" (windows XP). THUS, I've redefined "_WIN32_WINNT=0x0501" for all of the projects that appear to be related to HttpWire. It is possible I missed one or two.
Was it helpful?

Solution

There is only 1 .cpp file in the project (HttpWire.cpp)

Well, that's a problem because clearly you need more than 1. You also need THttpWire.cpp since it contains the constructor code. The one that the linker cannot find.

Keep the C++ build model in mind, it is very different from C#. Source code files are separately compiled. And then the linker glues all the bits of code together to make the program. Those bits may come from an .obj file created from a .cpp file. Or they could come from a .lib file, a "container" of bits of code.

Which is the likely explanation since you mentioned an "AirTime Core" project. Project + Properties, Linker, Input, Additional Dependencies setting. You need to add the output of the "AirTime Core" project, whatever it is named.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top