最近开始研究 QGIS 3.4.x,QGIS 3.4.x 改为 一个console做启动,读取环境配置文件,另外把qgis应用做成一个dll,由console启动。这样的好处就是QGIS可以做成绿色软件,降低对环境变量配置要求。
好了,不多说,直接上代码。
一、console代码,直接改自qgis的代码
#include <windows.h>
#include <io.h>
#include <sstream>
#include <iostream>
#include <fstream>
#include <list>
#include <memory>
void showError( std::string message, std::string title )
{
std::string newmessage = "Oops, looks like an error loading QGIS \n\n Details: \n\n" + message;
MessageBox(
NULL,
newmessage.c_str(),
title.c_str(),
MB_ICONERROR | MB_OK
);
std::cerr << message << std::endl;
}
std::string moduleExeBaseName( void )
{
DWORD l = MAX_PATH;
std::unique_ptr<char> filepath;
for ( ;; )
{
filepath.reset( new char[l] );
if ( GetModuleFileName( nullptr, filepath.get(), l ) < l )
break;
l += MAX_PATH;
}
std::string basename( filepath.get() );
basename.resize( basename.length() - 4 );
return basename;
}
int CALLBACK WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
std::string basename( moduleExeBaseName() );
try
{
std::ifstream file;
file.open( basename + ".env" );
std::string var;
while ( std::getline( file, var ) )
{
if ( _putenv( var.c_str() ) < 0 )
{
std::string message = "Could not set environment variable:" + var;
showError( message, "Error loading QGIS" );
return EXIT_FAILURE;
}
}
}
catch ( std::ifstream::failure e )
{
std::string message = "Could not read environment file " + basename + ".env" + " [" + e.what() + "]";
showError( message, "Error loading QGIS" );
return EXIT_FAILURE;
}
HINSTANCE hGetProcIDDLL = LoadLibrary( "MyPowerApp.dll" );
if ( !hGetProcIDDLL )
{
DWORD error = GetLastError();
LPTSTR errorText = NULL;
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error,
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
( LPTSTR )&errorText,
0,
NULL );
std::string message = "Could not load qgis_app.dll \n Windows Error: " + std::string( errorText )
+ "\n Help: \n\n Check " + basename + ".env for correct environment paths";
showError( message, "Error loading QGIS" );
LocalFree( errorText );
errorText = NULL;
return EXIT_FAILURE;
}
int ( *realmain )( int, char *[] ) = ( int ( * )( int, char *[] ) ) GetProcAddress( hGetProcIDDLL, "main" );
if ( !realmain )
{
showError( "Could not locate main function in qgis_app.dll", "Error loading QGIS" );
return EXIT_FAILURE;
}
return realmain( __argc, __argv );
}
二、dll代码
#include "mypowerapp_global.h"
#include "QgsApplication.h"
#include "QPowerMain.h"
int MYPOWERAPP_EXPORT main(int argc, char *argv[])
{
QgsApplication a(argc, argv, true);
QgsApplication::initQgis(); //初始化QGIS应用
QPowerMain w; //创建一个窗体,类似于Qt
w.show();
return a.exec();
}
记得要设置main为MYPOWERAPP_EXPORT。其他的跟往常一样。