从main.cc开始
//-----------------------------------------------------------------------------
/**
* @brief Starts the application
*
* @param argc Number of commandline arguments
* @param argv Commandline arguments
* @return exit code, 0 for normal exit and !=0 for error cases
*/
int main(int argc, char *argv[])
{
#ifndef __mobile__
// We make the runguard key different for custom and non custom
// builds, so they can be executed together in the same device.
// Stable and Daily have same QGC_APPLICATION_NAME so they would
// not be able to run at the same time
QString runguardString(QGC_APPLICATION_NAME);
runguardString.append("RunGuardKey");
qDebug()<<"argc: "<<argc;
for(int i = 0; i < argc; ++i) {
qDebug()<<"argv["<<i<<"]: "<<argv[i];
}
qDebug()<<"runguardString: "<<runguardString;
RunGuard guard(runguardString);
if (!guard.tryToRun()) {
// QApplication is necessary to use QMessageBox
QApplication errorApp(argc, argv);
QMessageBox::critical(nullptr, QObject::tr("Error"),
QObject::tr("A second instance of %1 is already running. Please close the other instance and try again.").arg(QGC_APPLICATION_NAME)
);
return -1;
}
#endif
//-- Record boot time
QGC::initTimer();
// install the message handler
AppMessages::installHandler();
#ifdef Q_OS_WIN
// Set our own OpenGL buglist
qputenv("QT_OPENGL_BUGLIST", ":/opengl/resources/opengl/buglist.json");
// Allow for command line override of renderer
for (int i = 0; i < argc; i++) {
const QString arg(argv[i]);
if (arg == QStringLiteral("-angle")) {
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
break;
} else if (arg == QStringLiteral("-swrast")) {
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
break;
}
}
#endif
// The following calls to qRegisterMetaType are done to silence debug output which warns
// that we use these types in signals, and without calling qRegisterMetaType we can't queue
// these signals. In general we don't queue these signals, but we do what the warning says
// anyway to silence the debug output.
#ifndef NO_SERIAL_LINK
qRegisterMetaType<QSerialPort::SerialPortError>();
#endif
qRegisterMetaType<QAbstractSocket::SocketError>();
#ifndef __mobile__
#ifndef NO_SERIAL_LINK
qRegisterMetaType<QGCSerialPortInfo>();
#endif
#endif
qRegisterMetaType<Vehicle::MavCmdResultFailureCode_t>("Vehicle::MavCmdResultFailureCode_t");
// We statically link our own QtLocation plugin
#ifdef Q_OS_WIN
// In Windows, the compiler doesn't see the use of the class created by Q_IMPORT_PLUGIN
#pragma warning( disable : 4930 4101 )
#endif
Q_IMPORT_PLUGIN(QGeoServiceProviderFactoryQGC)
bool runUnitTests = false; // Run unit tests
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QGCApplication* app = new QGCApplication(argc, argv, runUnitTests);
Q_CHECK_PTR(app);
if(app->isErrorState()) {
app->exec();
return -1;
}
// There appears to be a threading issue in qRegisterMetaType which can cause it to throw a qWarning
// about duplicate type converters. This is caused by a race condition in the Qt code. Still working
// with them on tracking down the bug. For now we register the type which is giving us problems here
// while we only have the main thread. That should prevent it from hitting the race condition later
// on in the code.
qRegisterMetaType<QList<QPair<QByteArray,QByteArray> > >();
app->_initCommon();
//-- Initialize Cache System
getQGCMapEngine()->init();
int exitCode = 0;
{
if (!app->_initForNormalAppBoot()) {
return -1;
}
exitCode = app->exec();
}
app->_shutdown();
delete app;
//-- Shutdown Cache System
destroyMapEngine();
qDebug() << "After app delete";
return exitCode;
}
* RunGuard-防止同一版本的多个程序同时运行
We make the runguard key different for custom and non custom builds, so they can be executed together in the same device.Stable and Daily have same QGC_APPLICATION_NAME so they would not be able to run at the same time。
这里打印int argc,char *argv[]得到:
argc: 1
argv[ 0 ]: D:\Work\qgc4.2.9\build-qgroundcontrol-Desktop_Qt_5_15_2_MSVC2019_64bit-Release\staging\QGroundControl.exe
这个打印结果是正常的,我使用的是qt creator直接运行的,没有用命令行添加指令参数运行。新创建一个qt项目打印这两项也基本一样,argv是可执行程序的路径。
先来看main函数中的第一段代码:
QString runguardString(QGC_APPLICATION_NAME);
runguardString.append("RunGuardKey");
RunGuard guard(runguardString);
if (!guard.tryToRun()) {
// QApplication is necessary to use QMessageBox
QApplication errorApp(argc, argv);
QMessageBox::critical(nullptr, QObject::tr("Error"),
QObject::tr("A second instance of %1 is already running. Please close the other instance and try again.").arg(QGC_APPLICATION_NAME)
);
return -1;
}
QGC_APPLICATION_NAME在qgroundcontrol.pro,也就是Qt工程文件中中定义:
DEFINES += QGC_APPLICATION_NAME=\&#