NuGet Curl C++. Unresolved external symbol only with x64 build - c++

I have already searched a solution on Google and here on SO I have only found some questions about the non-NuGet lib package.
(This is the NuGet package. I use the 7.52.1 version because the 7.53.0 has some compatibility problems with the program I'm developing even with the x86 build)
My problem is that when I want to build my project to x64, the linker gives me 149 errors about an unresolved external symbol in libcurl.lib (openssl.obj), (md5.obj) and (curl_ntlm_core.obj).
I'm 90% sure that everything is ok about the project settings for the x64 part, I have verified and re-verified a lot of times before asking here for help.
This is the code I use (who works on the x86 build):
#include <string>
#pragma comment(lib, "wldap32.lib")
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "Ws2_32.lib")
#define CURL_STATICLIB
#include <curl\curl.h>
class _Curl {
private:
static size_t _CURLWriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
public:
static BOOL DownloadString(const std::string &URL, std::string &strGET, LONG CONNECTION_TIMEOUT_MS = 1000) {
CURL* _CURL;
CURLcode _CURL_RESPONSE;
_CURL = curl_easy_init();
if (_CURL) {
curl_easy_setopt(_CURL, CURLOPT_URL, URL.c_str());
curl_easy_setopt(_CURL, CURLOPT_CONNECTTIMEOUT_MS, CONNECTION_TIMEOUT_MS);
curl_easy_setopt(_CURL, CURLOPT_WRITEFUNCTION, _CURLWriteCallback);
curl_easy_setopt(_CURL, CURLOPT_WRITEDATA, &strGET);
_CURL_RESPONSE = curl_easy_perform(_CURL);
curl_easy_cleanup(_CURL);
}
if (_CURL_RESPONSE == CURLE_OK) { return TRUE; }
return FALSE;
}
};
I have also tried to change this part
#pragma comment(lib, "wldap32.lib")
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "Ws2_32.lib")
With
#pragma comment(lib, "wldap64.lib")
#pragma comment(lib, "crypt64.lib")
#pragma comment(lib, "Ws2_64.lib")
But seems that the names of the libs are hardcoded to *32.lib
I want to say sorry if this will be a duplicate, but I can't find a solution for my case.
P.S: I'm using Visual Studio Community 2017
Thank you for your time!
[UPDATE]
I can't seem to find a solution to make curl to work also with the x64 build.
So I have solved using WinINet (because I only need to download the HTML content of a Web page as a string).
I have created a small class to do this, the "only" problem is that WinINet seems to be much slower (approximately with a 48% slower [I have only tested with some files large between 100KB and 800KB]).
This is the class I have written if someone has the same problem and want to use a "workaround"
#ifndef _NET_H
#define _NET_H
#include <iostream>
#include <string>
#include <tchar.h>
#include <Windows.h>
#include <WinINet.h>
#pragma comment(lib, "WinINet.lib")
class _Net {
public:
static BOOL DownloadString(const std::basic_string<TCHAR> &URL, std::basic_string<TCHAR> &RETURN, DWORD CONNECTION_TIMEOUT_MS = 1000, DWORD CONNECTION_RETRIES = 1) {
if (InternetCheckConnection(_T("http://www.google.com"), FLAG_ICC_FORCE_CONNECTION, 0) == FALSE)
return 0;
HINTERNET _hOpen = InternetOpen(0, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0);
if (!_hOpen)
return 0;
InternetSetOption(_hOpen, INTERNET_OPTION_SEND_TIMEOUT
& INTERNET_OPTION_RECEIVE_TIMEOUT
& INTERNET_OPTION_CONNECT_TIMEOUT, &CONNECTION_TIMEOUT_MS, sizeof(DWORD));
InternetSetOption(_hOpen, INTERNET_OPTION_CONNECT_RETRIES, &CONNECTION_RETRIES, sizeof(DWORD));
DWORD _f = INTERNET_FLAG_DONT_CACHE |
INTERNET_FLAG_SECURE |
INTERNET_FLAG_NO_CACHE_WRITE |
INTERNET_FLAG_PRAGMA_NOCACHE |
INTERNET_FLAG_IGNORE_CERT_CN_INVALID |
INTERNET_FLAG_IGNORE_CERT_DATE_INVALID;
HINTERNET _hInternet = InternetOpenUrl(_hOpen, URL.c_str(), 0, 0, _f, 0);
if (!_hInternet) {
CloseHandle(_hOpen);
return 0;
}
TCHAR _data[2]; ZeroMemory(&_data, sizeof(_data));
DWORD _dataReceivedSize;
std::basic_string<TCHAR> _strResult;
while (InternetReadFile(_hInternet, _data, 1, &_dataReceivedSize) && _dataReceivedSize)
_strResult += _data;
CloseHandle(_hInternet);
CloseHandle(_hOpen);
if (_strResult.length() == 0)
return 0;
RETURN = _strResult;
return 1;
}
};
#endif //_NET_H
This will download the Web page from the given url, and return the content in the RETURN string.
std::string content;
_Net::DownloadString("https://www.google.com", content);

Related

ssh_connect: Library not initialized (LibSSH)

I have the following piece of code which I am trying to build statically, so I end up with a single executable.
#define LIBSSH_STATIC 1
#include <libssh/libssh.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <errno.h>
#include <string.h>
#pragma comment(lib, "mbedcrypto.lib")
#pragma comment(lib, "pthreadVSE3.lib")
#pragma comment(lib, "ssh.lib")
#pragma comment(lib, "Ws2_32.lib")
int main()
{
ssh_session my_ssh_session;
int method, rc;
int port = 22;
const char* password;
int verbosity = SSH_LOG_FUNCTIONS;
//int stricthostcheck = 0;
std::string host = "10.10.10.100";
std::string user = "user";
// Open session and set options
my_ssh_session = ssh_new();
if (my_ssh_session == NULL)
exit(-1);
ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, host.c_str());
ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &port);
ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, user.c_str());
ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
// Connect to server
rc = ssh_connect(my_ssh_session);
if (rc != SSH_OK)
{
fprintf(stderr, "Error: %s\n", ssh_get_error(my_ssh_session));
ssh_free(my_ssh_session);
exit(-99);
}
// Authenticate ourselves
password = "Password";
rc = ssh_userauth_password(my_ssh_session, NULL, password);
if (rc != SSH_AUTH_SUCCESS)
{
fprintf(stderr, "Error authenticating with password: %s\n",
ssh_get_error(my_ssh_session));
ssh_disconnect(my_ssh_session);
ssh_free(my_ssh_session);
exit(-1);
}
ssh_disconnect(my_ssh_session);
ssh_
free(my_ssh_session);
}
I have installed the following libraries using VCPKG
libssh:x86-windows-static
zlib:x86-windows-static
openssh:x86-windows-static
I have manually linked the following include path, in the C/C++ section of project properties on the General tab under Additional include directories
C:\dev\vcpkg\installed\x64-windows-static\include
I have also under in the Linker section of project properties, also on its General tab, added an entry for Additional library directories
C:\dev\vcpkg\installed\x64-windows-static\lib
The additional libraries are linked in the code, using the following four lines of code:
#pragma comment(lib, "mbedcrypto.lib")
#pragma comment(lib, "pthreadVSE3.lib")
#pragma comment(lib, "ssh.lib")
#pragma comment(lib, "Ws2_32.lib")
I have also set the C/C++, Code Generation, Runtime option to Multi-Threaded (/MT)
When I run the program it compiles fine, creating a single executable. However, when I run the program, I get an error stating "ssh_connect: Library not initialized"
This is day three of trying to get this to work, with no previous knowledge of how to compile applications. Any help greatly appreciated :)
3 days spent on guessing instead of reading the manual - it's unbelievable. Almost on the top:
If libssh is statically linked, threading must be initialized by calling
ssh_init() before using any of libssh provided functions. This initialization
must be done outside of any threading context. Don't forget to call
ssh_finalize() to avoid memory leak
By the way, any examples of libbssh usage have calls to ssh_init() and ssh_finalize(). You can look at the unit tests.

How to find the "Saved Games" folder programmatically in C/C++?

I am writing a game. I am planning to store saves in the "saved games" directory.
How to find the location of the Saved Games folder programmatically?
It needs to work on non-English Windows. Hacks like %USERPROFILE%\Saved Games are not an option.
The Saved Games directory can be located with the SHGetKnownFolderPath() function, available since Windows Vista and Windows Server 2008.
Note that the FOLDERID_SavedGames argument is a C++ reference. Replace with &FOLDERID_SavedGames to call from C code.
Tested successfully on the first online MSVC compiler I could find:
https://rextester.com/l/cpp_online_compiler_visual
#define WINVER 0x0600
#define _WIN32_WINNT 0x0600
#include <stdio.h>
#include <shlobj.h>
#include <objbase.h>
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "ole32.lib")
int main(void)
{
PWSTR path = NULL;
HRESULT r;
r = SHGetKnownFolderPath(FOLDERID_SavedGames, KF_FLAG_CREATE, NULL, &path);
if (path != NULL)
{
printf("%ls", path);
CoTaskMemFree(path);
}
return 0;
}

The LPCSTR type string is garbled or displayed error

I have a LPCSTR that I want to convert to std::string or char*.
LPCSTR strName;
_tprintf(_T("%s\n"), strName);
I'm trying to get all the audio equipment on the computer and displayed, but to get the LPCSTR type of direct output is garbled, use the above code to output the correct results.
Is there a way to save the correct output?
The following is the complete code:
Add a dependency to the property:
comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;odbc32.lib;odbccp32.lib
ListSoundDev.h
#ifndef _LISTSOUNDDEV_HEAD_
#define _LISTSOUNDDEV_HEAD_
#include<tchar.h>
#include <dshow.h>
#include<iostream>
#include<vector>
#include<mmsystem.h>
#include<mmreg.h>
#include<dsound.h>
#pragma comment(lib, "strmiids.lib")
#pragma comment(lib, "Quartz.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "dsound.lib")
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "strmiids")
using namespace std;
typedef struct _DevItem
{
LPCSTR strName;
GUID guid;
} DevItem;
#endif
main.cpp
#include"ListSoundDev_head.h"
std::vector<DevItem> m_CapDevices;
BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext)
{
std::vector<DevItem> *pLst = (std::vector<DevItem> *) lpContext;
if (pLst)
{
DevItem item;
memset(&item, 0, sizeof(item));
item.strName = lpcstrDescription;
if (lpGuid)
item.guid = *lpGuid;
else
item.guid = GUID_NULL;
pLst->push_back(item);
return TRUE;
}
return FALSE;
}
int main()
{
std::vector<DevItem>::iterator it;
HRESULT hr = S_OK;
setlocale(LC_ALL, "chs");
hr = DirectSoundCaptureEnumerate((LPDSENUMCALLBACKW)DSEnumCallback, (LPVOID)&m_CapDevices);
for (it = m_CapDevices.begin(); it != m_CapDevices.end(); it++){
_tprintf(_T("%s\n"), it->strName);//output correct
printf("%s\n",it->strName);//output error
std::cout << it->strName << std::endl;//output error
}
}
Expected output:
麦克风 (Realtek High Definition Au
Actual output:
KQ螛
Expected output:
Realtek Digital Input (Realtek
Actual output:
R
How can I that printf() or std::cout can directly output the correct results?
Thank you very much for your answer, I have solved this problem.
The solution is to use the following code to convert.
The character set is Unicode.
char newStr[100];
wcstombs(newStr, (wchar_t*)it->strName, 100);
printf("newStr=%s\n", newStr);
The character set is Multibyte
printf("%s\n", it->strName);
However, when I write this program in the C + + console to obtain the name of the audio device for the microphone (Realtek High Definition Au, but in MFC using this code to get the device name for the microphone (Realtek High Definition Audio) What is the reason?

NetUserChangePassword C++

I would like to change user password on my Windows 7 PC using C++.
But when I compile it gets error:
undefined reference to 'NetUserChangePassword'
[Error] ld returned 1 exit status.`
How can I fix it?
Here is the MSDN page with the NetUserChangePassword function:
#ifndef UNICODE
#define UNICODE
#endif
#pragma comment(lib, "netapi32.lib")
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <lm.h>
bool ChangeUserPassword(LPCWSTR OldPassword, LPCWSTR NewPassword)
{
NET_API_STATUS nStatus;
LPTSTR lp = new TCHAR[256];
DWORD dw = 256;
GetUserName(lp, &dw);
nStatus = NetUserChangePassword(NULL, lp, OldPassword, NewPassword);
delete[] lp;
if (nStatus == NERR_Success)
return true;
return false;
}
int main(int argc, char** argv)
{
LPCWSTR Old_P = L"C";
LPCWSTR New_P = L"D";
ChangeUserPassword(Old_P, New_P);
return 0;
}
I tried to link to the project the winapi32.dll in two ways
i tried to add using the project option
i tried to add following line
HINSTANCE hInst = LoadLibrary( L"C:\\Windows\\System32\\netapi32.dll ");
but i get always the same error
The requirements section of the MSDN topic you linked to states that you must link the Netapi32.lib library. That is the step that you have missed and explains the missing external error.
As to how to resolve the problem it is hard to say for sure. You are not using the MS compiler and so the #pragma approach won't work. Consult the docs for your compiler/linker to work out how to link this library.
It looks like you are using a GCC based compiler and so need to add -lnetapi32 to the options.

LNK2019: Error. unresolved external symbol in C++ program using InternetOpen InternetReadFIle

I have tried writing a simple program to get information from a website. I can't compile as I get the LNK2019 error for InternetReadFile, InternetOpenUrl, etc. and e.g.
1>GetInternetInfo.obj : error LNK2019: unresolved external symbol _imp_InternetReadFile#16 referenced in function _main
I assume that means I did not define these functions, that I did not include the correct library. I thought including #include would fix it, but it does not seem to help. I am running this on Visual Studio 2010 using C++. Below is my program. Any help is appreciated.
#include <string>
#include <iostream>
#include <fstream>
#include <windows.h>
#include <wininet.h>
#include <winsock.h>
#include <stdio.h>
#include <stdarg.h>
using namespace std;
int main()
{
HINTERNET hOpen, hURL;
LPCWSTR NameProgram = L"Webreader"; // LPCWSTR == Long Pointer to Const Wide String
LPCWSTR Website;
char file[101];
unsigned long read;
//Always need to establish the internet connection with this funcion.
if ( !(hOpen = InternetOpen(NameProgram, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 )))
{
cerr << "Error in opening internet" << endl;
return 0;
}
Website = L"http://www.google.com";
hURL = InternetOpenUrl( hOpen, Website, NULL, 0, 0, 0 ); //Need to open the URL
InternetReadFile(hURL, file, 100, &read);
while (read == 100)
{
InternetReadFile(hURL, file, 100, &read);
file[read] = '\0';
cout << file;
}
cout << endl;
InternetCloseHandle(hURL);
return 0;
}
Please include "Wininet.lib" in your project settings.
Project->Properties->Configuration Properties->Linker->Input->Additional Dependencies
You can also add this line to your code after include section instead of adding library to the properties:
#pragma comment(lib, "wininet.lib")
Did you link to wininet.lib?
http://msdn.microsoft.com/en-us/library/aa385103(VS.85).aspx