I want to use git from an Qt application. So far, I use QProcess, but I do not want to use that. So I found libgit2.
This works as expected:
#include <QApplication>
#include "git2.h"
int main(int argc, char* argv[])
{
git_repository* repo = 0;
git_clone(&repo, "/path_to/barerep", "/path_to/test_clone", NULL);
git_repository_free(repo);
repo = 0;
}
But here, git_clone crashes.
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
git_repository* repo = 0;
git_clone(&repo, "/path_to/barerep", "/path_to/test_clone", NULL);
git_repository_free(repo);
repo = 0;
return a.exec();
}
The error is:
*** Error in `/path_to/gittest': free(): invalid pointer: 0x09d53a88 ***
Any suggestions? Of course, omitting QApplication is not an alternative. The same error occurs without return a.exec().
Note: Actually, there is a class GitRepository with a method clone(const QString & url) (the path is stored somewhere in the class).
Again, this works
int main(int argc, char* argv[])
{
GitRepository g;
g.clone("path_to/barerep");
}
But this does not. (QObject!)
int main(int argc, char* argv[])
{
QObject(); // <--
GitRepository g;
g.clone("path_to/barerep");
}
does not.
bool GitRepository::clone(const QString & url)
{
git_repository* repo = 0;
git_clone(&repo, CSTR(url), CSTR(path()), NULL);
git_repository_free(repo);
repo = 0;
//loadFromTempDir();
return true;
}
Replacing QApplication by QObject in the first example suppresses the error.
You need to call git_libgit2_init() before calling any other libgit2 functions. As the documentation says:
This function must the called before any other libgit2 function in order to set up global state and threading.
These kind of errors are really hard to find. I also had problems mixing Qt libraries with other libraries. The trick is to organize your code in a way that there is only one library included in one compilation unit.
Create a class, which wraps around libgit2, and only include the libgit2 headers in the cpp file of this class. Do not include any qt headers in the same file.
Only refer to libgit throw your wrapper. Sure it seems like a lot of work, but as a result your code will be cleaner, and these misterious errors will be gone.
Related
I'm unable to get command line argument with int main(int argc, char* argv[]), No errors occurs but when further manipulation want to happen i see that argv[ ] and other related variables dont have any value and says Error reading characters of string then an Acces violation reading location error happens.
This is the sample code of my issue, I had to downsize it to make it readable:
#include "CommonHeaders.h"
void Start(char *input)
{
lstrcpyA(host, input);
// In this point i see in my Debugger "Locals/Autos" that nothing
// is passed to function then a "Access violation ... " happens.
// ...
}
int main(int argc, char *argv[])
{
Start(argv[1]);
return 0;
}
I always use this int main(int argc, char* argv[]) and pass command arg with ProjectProperties->Debugging->Command Argument and works perfect everytime. Is it possible that proper headers aren't included or any changes in project configuration could make a conflict?
Be sure to set the subsystem to console Linker -> SubSytem -> Console (/SUBSYSTEM:CONSOLE) and dont set an Entry point set the Whole Program Optimization to No Whole Program Optimization and turn SDL check to off.
I have a very strange problem while trying to run a QProcess in a class HmiApplication, which is derived from QApplication.
The application throws a SIGSEGV in line 6 of main.cpp. This occurs only if line 11 of hmiapplication.cpp is commented out (If I don't qDebug() the stdout of the QProcess).
For the sake of simplicity and clarity, I didn't handle any return values while creating the QProcess.
main.cpp
#include "hmiapplication.h"
int main(int argc, char **argv)
{
HmiApplication hmi(argc, argv);
return hmi.exec(); // LINE 6 - SIGSEGV
}
hmiapplication.h
#ifndef HMIAPPLICATION_H
#define HMIAPPLICATION_H
#include <QApplication>
#include <QProcess>
class HmiApplication : public QApplication
{
Q_OBJECT
public:
HmiApplication(int argc, char **argv);
virtual ~HmiApplication();
private:
QProcess *macFinder = nullptr;
};
#endif // HMIAPPLICATION_H
hmiapplication.cpp
#include "hmiapplication.h"
HmiApplication::HmiApplication(int argc, char **argv) : QApplication(argc, argv)
{
macFinder = new QProcess(this);
macFinder->start("arping", QStringList() << "-c 2" << "192.168.1.1");
macFinder->waitForReadyRead();
QString ret(macFinder->readAllStandardOutput());
ret = ret.mid(ret.indexOf('[') + 1, 17);
qDebug() << ret; // LINE 11
}
HmiApplication::~HmiApplication()
{
}
EDIT:
If I add QVector<Camera*> cameras; to the header and
for(quint8 i = 0; i < 10; i++) {
Camera *cam = new Camera(i);
cameras.append(cam);
}
to the source file, it doesn't matter whether or not I remove the qDebug() line and will throw a segmentation fault in both cases.
Camera is a derived class of QLabel and is perfectly working without the QProcess mentionened above.
The QApplication constructor accepts its first parameter by reference...
QApplication::QApplication(int &argc, char **argv)
With the documentation also warning that...
The data referred to by argc and argv must stay valid for the entire
lifetime of the QApplication object. In addition, argc must be greater
than zero and argv must contain at least one valid character string.
However, you pass argc by value to the HmiApplication. Hence the QApplication constructor receives a non-const reference to the local copy which will go out of scope at the end of the HmiApplication ctor leading to undefined behaviour later on.
Change the signature of your constructor to...
HmiApplication::HmiApplication(int &argc, char **argv)
I am new at Qt (and c++). I have a simple question:
What is wrong?
#include <QCoreApplication>
#include <QtNetwork/QLocalServer>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QLocalServer* x = new QLocalServer(this);
return a.exec();
}
Thank for advice.
Your problem is this (pun intended):
QLocalServer* x = new QLocalServer(this);
this is not valid outside non-static class member functions. main() is not a member function, and thus this doesn't exist. You can pass NULL pointer instead, to signify that the object shall have no parent:
QLocalServer* x = new QLocalServer(NULL);
Don't forget to add the network module in your project file's QT variable. For example:
QT += OTHER_MODULES_YOU_USE_HERE network
I'm trying to figure out why this is not working. I want to do like in Java where main is a static function in a class but this is producing unresolved external symbol error:
static class MainClass
{
public:
static int _tmain(int argc, char* argv[])
{
return 0;
}
};
Why doesn't this work?
Thanks
C++ does not work like that.
You need main as a function:
int main(int argc,char* argv[])
{
//STUFF
}
Because _tmain is mangled in the binary with the class name MainClass in it, so multiple classes could have a function _tmain in them and not conflict. It's not got the same mangled name as ::_tmain is going to have.
I remember that with an earlier version of MSVC, it accepted the following without a linker error which ended up accidentally as a result of macro expansion in my code base once
namespace bar {
int main() { }
}
It apparently treated the name main specially and didn't mangle it or mangle it the same as ::main. But such a thing is not Standard conformant. Like in the class case, such a function is completely unrelated to the main function.
_tmain is called from CRT. You need to set in your linker an entry point to another function that will call MainClass::_tmain instead.
Because, in C++, you cannot put an entry point inside a class. This answer might help.
Why doesn't that work? Because it's not C++.
struct MainClass {
static int main(int argc, char** argv) {
return 0;
}
};
int main(int argc, char** argv) {
return MainClass::main(argc, argv);
}
It's not really C++, so much as the standard linker process which is looking for an export of a specific name (with C-style linkage). The specific export varies based on the compiler and executable type, but the format is specific for each type. For example, Windows GUI exe's have different entry points than console, and specific for ASCII or UNICODE. But the linker is always looking for a function with a specific link name, which is why a static member won't work.
You always need main() defined as a global function. This is where the program always starts in C++. You could simple call your static class function from main and pass on the variables if you really want to:
class MainClass
{
public:
static int _tmain(int argc, char* argv[])
{
return 0;
}
};
int main(int argc, char* argv[]) {
return MainClass::_tmain(argc, argv);
}
I created an .exe file and associated .myFile extension to that .exe file. I want to double click on any .myFile file and get that file opened by the .exe. For that I have done the following:
int main(int argc, char *argv[])
{
QString fileName(QObject::tr(argv[1]));
if ( fileName != "" )
{
mainWin.loadFile(fileName);
}
..................
}
But when I have named my file in unicode characters (e.g. "Здравствуй.myFile"), the instead of "Здравствуй" you can see "????????". How to solve this problem? I know this is solved problem because, for example, MS Word does that.
The previous answers that focus on int main(int argc, char** argv) are needlessly complex. Qt has a better alternative.
From the Qt documentation: On Windows, the QApplication::arguments() are not built from the contents of argv/argc, as the content does not support Unicode. Instead, the arguments() are constructed from the return value of GetCommandLine().
So, the correct answer is to use qApp.arguments().at(1), which will give you the Unicode filename in a QString.
You have to use wmain instead of main on Windows:
int wmain(int argc, wchar_t** argv) {
QString fileName = QString::fromWCharArray(argv[1]); // untested
If you have to follow the C standard (which is all but useless on Windows), you can use GetCommandLineW and CommandLineToArgvW instead.
Assuming the unicode you pass in is actually stored as UTF-8, try using QString::fromUtf8 to read the argument, something like this:
int main(int argc, char *argv[])
{
QString fileName(QObject::trUtf8(argv[1]));
if ( fileName != "" )
{
mainWin.loadFile(fileName);
}
// stuff
}
QObject::trUtf8 is actually a wrapper that will utilize QString:fromUtf8 and still perform the translation (even though i dont understand why you want to translate file names)