When I pass the same unicode argument from QT5->Projects->Run the app works, but fails if passed as an argument directly to the exe. The arguments are being passed from an webpage encoded using encodeURIComponent in javascript.
The code is:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
if(a.arguments().count() < 2)
{
qFatal("No argument provided");
return EXIT_FAILURE;
}
QStringList args = a.arguments().at(1).split("####");
QString param1 = args.at(1);
QUrl downurl = QUrl::fromPercentEncoding(param.toLocal8Bit());
..........
}
Figured this out, using param.toUtf8() in the above code fixes this.
Related
I'm using Tcl 8.6 and I'm trying to do something like this to add functions to the tcl interpreter
Tcl_Interp* interp,
void init() {
interp = Tcl_CreateInterp();
}
void add_tcl_function(char* cmd, function<int(int,char**)> F) {
obj2argv* o2a = new obj2argv;
auto lambda_proc = [&](
ClientData cdata,
Tcl_Interp* interp,
int objc,
Tcl_Obj* const objv[])
{
o2a->set(objc, objv);
F(objc, o2a->get_argv());
};
auto lamba_delete = [&](
delete o2a;
};
Tcl_CreateObjCommand(interp, cmd, lamda_proc, NULL, lamda_delete);
}
What I'm wondering is how to convert "Tcl_Obj* const objv[]" to "char** argv"?
I was thinking about creating a class:
class obj2argv {
obj2argv();
void set(int objc, Tcl_Obj* const objv[]);
char** get_argv();
private:
//...
};
any ideas on how to implement set() and get_argv()?
Is there an easier way to do this?
Thanks.
obj2argv* o2a = new obj2argv;
If you're interfacing a function that's fundamentally working with const char** for arguments, you should register the function with Tcl_CreateCommand and let Tcl handle the mapping to strings for you. It already has all the mechanisms required.
More formally, you are dealing with a gluing function with this signature:
typedef int (Tcl_CmdProc) (ClientData clientData, Tcl_Interp *interp,
int argc, CONST84 char *argv[]);
The CONST84 should be read as being plain const in all new code, and ClientData is a pointer-sized value that Tcl just hands around and never inspects (same as with your existing code).
If you are going to do the mapping yourself, Tcl_GetString takes a Tcl_Obj* and returns the char* representation of it. The representation should be usually treated as const; it simply isn't formally typed as such for historical reasons.
I wanted to add some more information:
I gave up on using lambda's because when I added capture list it won't convert the lambda to a function pointer for some reason. So I went with the traditional approach (see below). EXCEPT: I still have not idea why the TCL document says
typedef int Tcl_CmdProc(
ClientData clientData,
Tcl_Interp *interp,
int argc,
const char *argv[]);
But the compiler requires this to compile:
typedef int Tcl_CmdProc(
ClientData clientData,
Tcl_Interp *interp,
int argc,
Tcl_Obj* const* argv);
The Code:
int cmd_dispatch(
ClientData clientData,
Tcl_Interp* interp,
int argc,
Tcl_Obj* const* argv)
{
function<int(int,char**)> F = *(function<int(int,char**)>*)clientData;
return F(argc, (char**) argv); // <= CAST DOESN'T SEEM RIGHT
}
void cmd_delete(ClientData clientData)
{
}
void add_tcl_function(const char* cmd, function<int(int,char**)> F) {
Tcl_CreateObjCommand(interp, cmd, cmd_dispatch, (void*)&F, cmd_delete);
}
VERSION 2:
struct cmd_data {
//Tcl_Interp* interp,
function<int(int,char**)> F;
int argc;
char* argv[MAX_ARGS];
};
int cmd_dispatch(
ClientData clientData,
Tcl_Interp* interp,
int argc,
Tcl_Obj* const* objv)
{
auto cmd_data1 = (struct cmd_data*) clientData;
cmd_data1->argc = argc;
for(int i=0; ((i < argc) && (i < MAX_ARGS)); i++) {
cmd_data1->argv[i] = Tcl_GetString(objv[i]);
// Who owns object returned by Tcl_GetString?
// memory leak? or invalid after return from function?
// garbage collected by tcl interp?
}
return cmd_data1->F(argc, cmd_data1->argv);
}
void cmd_delete(ClientData clientData)
{
auto cmd_data1 = (struct cmd_data*) clientData;
if (cmd_data1) {
delete cmd_data1;
}
}
void add_tcl_function(const char* cmd, function<int(int,char**)> F) {
auto cmd_data1 = new struct cmd_data;
cmd_data1->F = F;
Tcl_CreateObjCommand(interp, cmd, cmd_dispatch, (void*)cmd_data1, cmd_delete);
}
void init_tcl_commands() {
auto lambda_hello = [&](int argc ,char** argv) -> int {
cout << "HELLO WORLD!\n";
return 0;
};
tcl_backend::add_tcl_function("hello", lambda_hello);
}
On the app start i have a console window, so how not to show it?
(Without Using WinMain! Because its parameters don't match to QApp)
My main.cpp code is:
int main(int _nArgCount, char * _pArgValues[]) {
QApplication app(_nArgCount, _pArgValues);
//QMLblock
QString strQmlPath = "qrc:qml/main.qml";
QQmlApplicationEngine engine;
QQmlComponent component(&engine, QUrl(strQmlPath));
if (component.status() == QQmlComponent::Error) {
qDebug()<<"Error:"<<component.errorString();
return app.exec();
}
Gui gui(component);
gui.recreateGui();
//state machine block
QStateMachine machine;
....
....
....
return app.exec();
}
Consider this simple code snippet:
static void Foo(std::string&& arg) {
printf("(universal reference) = %s\n", arg.c_str());
}
static void Foo(const std::string&& arg) {
printf("(const universal reference) = %s\n", arg.c_str());
}
static void Foo(std::string& arg) {
printf("(reference) = %s\n", arg.c_str());
}
static void Foo(const std::string& arg) {
printf("(const reference) = %s\n", arg.c_str());
}
int main(int argc, const char * argv[]) {
std::string value{"value"};
const std::string const_value{"const_value"};
Foo(value);
Foo(const_value);
Foo(std::string("temporary"));
Foo("litteral");
}
The resulting output under Clang is:
(reference) = value
(const reference) = const_value
(universal reference) = temporary
(universal reference) = literal
Why is the value case not using the universal reference version of the function? I thought one of the key benefits of universal references was that they could accept both lvalues and rvalues?
PS: It's not possible to force it either:
static void Foo(std::string&& arg) {
printf("(universal reference) = %s\n", arg.c_str());
}
//static void Foo(const std::string&& arg) {
// printf("(const universal reference) = %s\n", arg.c_str());
//}
//
//static void Foo(std::string& arg) {
// printf("(reference) = %s\n", arg.c_str());
//}
//
//static void Foo(const std::string& arg) {
// printf("(const reference) = %s\n", arg.c_str());
//}
int main(int argc, const char * argv[]) {
std::string value{"value"};
const std::string const_value{"const_value"};
Foo(value); <--- FAILS COMPILING: No matching function for call to 'Foo'
// Foo(const_value);
Foo(std::string("temporary"));
Foo("literal");
}
UPDATE: It appears "universal references" are only for templates, not regular functions, which explains why the above is not working as I was expecting.
However here's a version using a templated function:
template<typename T>
static void Foo(T&& arg) {
printf("%s\n", arg.c_str());
}
int main(int argc, const char * argv[]) {
std::string value{"value"};
const std::string const_value{"const_value"};
Foo<std::string>(value); <--- FAILS COMPILING: No matching function for call to 'Foo'
Foo<std::string>(const_value); <--- FAILS COMPILING: No matching function for call to 'Foo'
Foo<std::string>(std::string("temporary"));
Foo<std::string>("literal");
}
Why is the value case still not working through universal references (I understand why the const_value case is not)?
UPDATE: For reference, here's the final version that works with both lvalues and rvalues:
template<typename T>
static void Foo(T&& arg) {
printf("%s\n", arg.c_str());
}
int main(int argc, const char * argv[]) {
std::string value{"value"};
const std::string const_value{"const_value"};
Foo(value);
Foo(const_value);
Foo(std::string("temporary"));
//Foo("literal"); <--- Cannot work anyway since template is instantiated with arg as a const char*
}
Those are not "universal references". Those are merely rvalue references.
A "universal reference" (FYI: this term has fallen out of disfavor) refers explicitly to an rvalue reference applied directly to a fully template deduced type (as opposed to something like vector<T> &&v, which is only partially deduced) when using template argument deduction. None of your functions are template functions, so they behave like regular rvalue references.
foo(value) calls the lvalue reference version because variables passed as parameters bind to lvalue reference parameter types.
However here's a version using a templated function:
None of those functions use template argument deduction. You're explicitly specifying the template parameter directly, not allowing it to be deduced by the arguments you call it with.
Or more to the point:
Foo<std::string>(value);
Foo(value);
Foo<std::string>(std::string("temporary"));
Foo(std::string("temporary"));
In the first case, T is std::string, because you specified it to be so. Therefore, Foo<std::string> takes a std::string&&. value cannot bind to an rvalue reference, so it's a compile error.
In the second case, T is deduced through template argument deduction based on the argument expression. value is an lvalue, so T is deduced as std::string&. Therefore, Foo in this case takes a std::string& &&, which devolves down to std::string&.
In the third case, T is std::string. Therefore again, Foo<std::string> takes a std::string&&. A temporary can bind to an rvalue reference just fine, so it does so.
In the fourth case, T is deduced through template argument deduction based on the argument expression. The expression is a std::string temporary prvalue, so T is deduced as std::string (note the lack of references). So Foo in this case takes a std::string&&.
how can i check whether a specific window is open or not. I only got part of the window's name. i thinking of using EnumWindows() in QT console app but i get a few errors stating "main.obj:-1: error: unresolved external symbol imp__GetWindowTextW#12 referenced in function "int __stdcall EnumWindowsProc(struct HWND *,long)" (?EnumWindowsProc##YGHPAUHWND__##J#Z)"
Below is my sample code
BOOL CALLBACK EnumWindowsProc(HWND hWnd, long lParam) {
char buff[255];
if (IsWindowVisible(hWnd)) {
GetWindowText(hWnd, (LPWSTR) buff, 254);
}
return TRUE;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
EnumWindows(EnumWindowsProc, 0);
return 0;
}
That's a linker error rather than a compile error.
You have correctly included windows.h but you also need to add the import libraries to your linker options. All three Win32 functions in your sample code require you to link user32.lib.
EnumWindowsProc is not from Qt, it's a windows API function, you need to include windows.h
I did not use Qt, and the code can pass complie, but the output seems NOT right. Anyway, here's my code
#include <conio.h>
#include <iostream>
#include <windows.h>
using namespace std;
char buff[255];
BOOL CALLBACK EnumWindowsProc(HWND hWnd, long lParam)
{
if (IsWindowVisible(hWnd))
{
GetWindowText(hWnd, (LPWSTR) buff, 254);
}
return TRUE;
}
int main()
{
EnumWindows(EnumWindowsProc, 0);
for(int i = 0; i != 254; ++i)
cout << buff[i];
getch();
return 0;
}
You can use:
Application.OpenForms["FormName"]
To check if the form is open or not.
I am creating my first web service client using gsoap. I was able to the run the calc example provided with gsoap.
Now I am trying to access String GetData() function from WCF Webservice. I did the wsdl2h and soapcpp2 steps and have generated the .h file. In xxxxproxy.h I see that the prototype of GetData is as follows
/// Web service operation 'GetData' (returns error code or SOAP_OK)
virtual int GetData(_ns1__GetData *ns1__GetData, _ns1__GetDataResponse *ns1__GetDataResponse);
Can someone tell me what should I write in my main.cpp to access GetData. I have following code in main.cpp
#include <QtCore/QCoreApplication>
#include "soapWSHttpBinding_USCOREIAquaLinkProxy.h"
#include "WSHttpBinding_USCOREIAquaLink.nsmap"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
WSHttpBinding_USCOREIAquaLinkProxy webService;
std::cout <<"Sent request"<<std::endl;
std::string result;
if(webService.GetData(?????? )==SOAP_OK)
{
std::cout << "Returned "<< ????? <<std::endl;
}
else
{
webService.soap_stream_fault(std::cerr);
}
return a.exec();
}
Thanks.
The first argument _ns1__GetData in the function GetData is the request argument, the second is the response argument. You should try following:
_ns1__GetData request;
request.???? = ???? // I don't know the WCF Webservice
_ns1__GetDataResponse response;
if(webService.GetData(&request, &response) == SOAP_OK)
{
std::cout << "Returned " << response.????;
}
I don't know the WCF Webservice. But I guess that you have to fill the request instance with some values. What makes me wonder is, that the class names _ns1__GetData and _ns1__GetDataResponse begin with an underscore. I'm using gSoap for a long time and the names were always without beginning underscore.