PDA

View Full Version : URLDownloadToFile, TCHAR, string, wrong type.



darkrptyp
7th December 2011, 22:13
I have sth like that



#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtGui>
#include <QApplication>
//#include <config.h>

#include <qt_windows.h>

typedef HRESULT (*P_URLDownloadToFile)(
LPUNKNOWN pCaller,
LPCTSTR szURL,
LPCTSTR szFileName,
DWORD dwReserved,
void*
);


TCHAR path[] = TEXT("http://webpage.com/index.php");
TCHAR filew[] = TEXT("file.name");
wchar_t ur[] = TEXT("urlmon.dll");

P_URLDownloadToFile _URLDownloadToFile;

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;

HRESULT uRet = 1;
HINSTANCE hLib;
HMODULE urlmon=LoadLibrary(ur);
if(urlmon){ _URLDownloadToFile=(P_URLDownloadToFile)GetProcAdd ress(urlmon,"URLDL2F"); }
uRet = _URLDownloadToFile(NULL,path,filew,0,NULL);
if (uRet == S_OK)
{ qDebug() << "OK" << endl; }
else { qDebug() << "Wrong" << endl;}

FreeLibrary(hLib);

// Configsettings set_settings;
// set_settings.loadConfig();
w.show();
return a.exec();
}



When I was using this code in DevC++ it was working because insted of TCHAR and wchar_t I had "string". In QtCreator I had got errors like " cannot convert 'std::string' to 'const TCHAR*' in argument passing"

d_stranz
7th December 2011, 22:22
Where do you get this error? Line 32? Try putting L"URLDL2F" in the GetProcAddress call. The simple "URLDL2F" is a char * string, and Qt expects a Unicode TCHAR (wchar_t) string.

darkrptyp
8th December 2011, 08:39
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtGui>
#include <QApplication>
#include <config.h>

#include <qt_windows.h>

using namespace std;

typedef HRESULT (*P_URLDownloadToFile)(
LPUNKNOWN pCaller,
LPCTSTR szURL,
LPCTSTR szFileName,
DWORD dwReserved,
void*
);
//TCHAR path[] = TEXT("http://webpage.com/index.php");
//TCHAR filew[] = TEXT("file.name");

//wchar_t ur[] = TEXT("urlmon.dll");

string path = "http://dl.dropbox.com/u/18389601/prob.png";
string filew = "f.f";



P_URLDownloadToFile _URLDownloadToFile;

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;

HRESULT uRet = 1;
HINSTANCE hLib;
HMODULE urlmon=LoadLibrary("urlmon.dll"); // error for this line - cannot convert 'const char*' to 'const WCHAR*' for argument '1' to 'HINSTANCE__* LoadLibraryW(const WCHAR*)'
if(urlmon)
_URLDownloadToFile=(P_URLDownloadToFile)GetProcAdd ress(urlmon,"URLDownloadToFileA");


uRet = _URLDownloadToFile(NULL,path,filew,0,NULL); // error for this line - cannot convert 'std::string' to 'const TCHAR*' in argument passing
if ( uRet == S_OK )
{ qDebug() << "OK" << endl; }
else { qDebug() << "Wrong" << endl;}
// qDebug() << adres_new;

FreeLibrary(hLib);

// Configsettings set_settings;
// set_settings.loadConfig();

w.show();
return a.exec();
}

ChrisW67
8th December 2011, 10:07
This is, of course, absolutely nothing to with Qt.

Line 37, you are passing a "const char *" where the parameter type is "const WCHAR*". d_stranz has given you an approach for this.
Line 42, you are passing a std::string where the function is expecting a "const TCHAR*". There is no cast operator that the compiler can find. Try the c_str() member of std::string (better yet use a wstring).

When compiled with UNICODE (and/or _UNICODE) defined, as it is here, Windows functions expect wchar* arguments and the xyzW variant is called. When UNICODE is not defined the Windows functions require char* and the xyzA variant is called. The TCHAR and TEXT macros were used to make switching from standard to wide characters less tiresome. However, in general you should use the wide variants on Windows.
Read this: http://msdn.microsoft.com/en-us/library/ff381407%28VS.85%29.aspx

darkrptyp
8th December 2011, 22:03
uRet = _URLDownloadToFile(0,TEXT("http://www.google.com/index.html"),
TEXT("C:\\index.html"), 0,NULL);

I've tried also this method - L"some_text" - and uRet is the same.

uRet returns "-2146697203" (INET_E_UNKNOWN_PROTOCOL)
The same code from my second post works under DevCpp (add c_str(); to path, filew). I dont get it.
Is the problem that when I return TEXT("http://www.google.com/index.html") I get sth like that "0x75390000"?

edit://


std::wstring myurl(L"http://www.google.com/index.html" ); // or TEXT()
std::wstring myfile(L"C:\\index.html" ); // or TEXT()
uRet = _URLDownloadToFile(0,myurl.c_str(),myfile.c_str(), 0,NULL);

the same result.

ChrisW67
9th December 2011, 02:22
The same code from my second post works under DevCpp (add c_str(); to path, filew). I dont get it.
Clearly. When you build that code with DevCpp, without any of the Qt stuff presumably, the UNICODE macro is not set and all the function macros are defined to point to the ANSI versions and expect standard C char arguments. When you build it in a Qt project the UNICODE macro is set, because Qt needs it, and all the Windows API functions default to their wide character versions and expect wchar arguments. This is the sort of thing you see in the Windows header files:


#ifdef UNICODE
#define LoadLibrary LoadLibraryW
#else
#define LoadLibrary LoadLibraryA
#endif

So, when you use LoadLibrary() you are actually using LoadLibraryA() or LoadLibraryW() depending on UNICODE. There is no real reason to use the ANSI versions, or the TEXT and associated macros, any longer (as advised in the Microsoft page I linked to).

At the moment you are trying to mix the 8-bit (ANSI) version of URLDownloadToFileA, which is what you explicitly looked up from the DLL , with the arguments for the wide char version, i.e. URLDownloadToFileW. Look up the wide version or provide narrow char arguments. Your call.

Is there a reason you want to dynamically load a Windows DLL, rather than link to it at compile time or simply use Qt network classes without any of these hassles?