user3217883
user3217883

Reputation: 1463

Why unresolved external symbol for C++ WinInet functions?

I'm a Java programmer forced to do some C++. What a nightmare! I'm trying to send a POST request to a web service like this:

#include <Windows.h>
#include <tchar.h>
#include <WinInet.h>

    static TCHAR hdrs[] = _T("Content-Type: application/x-www-form-urlencoded");
    static TCHAR frmdata[] = _T("id=01&message=test_message");
    static LPCSTR accept[2] = { "*/*", NULL };
    static LPCWSTR tag = L"MyAgent";
    static LPCWSTR requestType = L"POST";

// for clarity, error-checking has been removed
HINTERNET hSession = InternetOpen(tag, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
HINTERNET hConnect = InternetConnect(hSession, _T("desktop-60nl2pl:9998"), INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
HINTERNET hRequest = HttpOpenRequest(hConnect, requestType, _T("/GUser/login"), NULL, NULL, (LPCWSTR*)accept, 0, 1);
HttpSendRequest(hRequest, hdrs, strlen((char*)hdrs), frmdata, strlen((char*)frmdata));

That code is based on this posting: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/dc74e7bf-3ac9-41a0-b1c7-ece14a76a906/send-post-request-to-simple-php-page-using-wininet?forum=vcgeneral

It compiles but doesn't link. Getting a bunch of these "unresolved external symbol _imp_InternetOpenW referenced in function "class std::vector

Sorry if this is a newby question but I'm not able to understand all the gobbldygook I read about linker errors. Can someone explain in simple terms?

Upvotes: 1

Views: 1286

Answers (2)

programmerj
programmerj

Reputation: 1684

You are referencing functions such as InternetOpen, but they are not defined in your code. The live in Win32 libraries that must be linked against your code. In this case, all the InternetXXXX functions live in the WinInet.lib static library and WinInet.dll dynamic link library. You must link against WinINet.lib for your program to compile.

Upvotes: 2

dgnuff
dgnuff

Reputation: 3557

TL;DR you're missing a library in your linker options.

Going from .cpp to .exe is a two step operation. Step one is compilation that converts .cpp to .obj. Step two is linking that converts .obj to .exe.

The reason to do this in two steps becomes very apparent when your program becomes big enough to require two or more .cpp files. You compile each .cpp on its own, and then link the two .objs together. That cuts your iteration time dramatically, especially when you have 100 or so .cpp files and have only changed one of them.

During the link phase, the linker also includes various libraries. Most of the really common ones are included automatically so everything just "works right"™ a reasonable percentage of the time. However less commonly used ones, e.g. networking libraries are not included by default and need to be explicitly named in the linker options.

Luckily, Microsoft make it pretty easy to track them down. Take one of the undefined function names, "undecorate" it to get the original back, e.g. InternetOpen and then google for InternetOpen msdn. The first link will take you here: https://msdn.microsoft.com/en-us/library/windows/desktop/aa385096(v=vs.85).aspx and if you scroll right to the bottom, there's a Requirements section. Listed in there is the library you want: wininet.lib so all you have to do is explicitly name it in the Additinal Dependencies field of the Input page of the Linker options under Project Properties, and you should be good to go.

You are using Visual Studio for this, right?

Upvotes: 1

Related Questions