QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
qgsservicenativeloader.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsservicerenativeloader.cpp
3
4 Define Loader for native service modules
5 -------------------
6 begin : 2016-12-05
7 copyright : (C) 2016 by David Marteau
8 email : david dot marteau at 3liz dot com
9 ***************************************************************************/
10
11/***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 ***************************************************************************/
19
20#include <QLibrary>
21#include <QDir>
22#include <QDebug>
23
25#include "qgsservicemodule.h"
26#include "qgsmessagelog.h"
27#include "qgis.h"
28
29
31
39{
40 public:
45 QgsServiceNativeModuleEntry( const QString &location )
46 : mLocation( location )
47 {}
48
49 QString mLocation;
52};
53
54void QgsServiceNativeLoader::loadModules( const QString &modulePath, QgsServiceRegistry &registrar, QgsServerInterface *serverIface )
55{
56 QDir moduleDir( modulePath );
57 moduleDir.setSorting( QDir::Name | QDir::IgnoreCase );
58 moduleDir.setFilter( QDir::Files );
59
60#if defined( Q_OS_WIN ) || defined( __CYGWIN__ )
61 moduleDir.setNameFilters( QStringList( "*.dll" ) );
62#else
63 moduleDir.setNameFilters( QStringList( "*.so" ) );
64#endif
65
66 // qDebug() << QString( "Checking %1 for native services modules" ).arg( moduleDir.path() );
67
68 const auto constFiList( moduleDir.entryInfoList() );
69 for ( const QFileInfo &fi : constFiList )
70 {
71 QgsServiceModule *module = loadNativeModule( fi.filePath() );
72 if ( module )
73 {
74 // Register services
75 module->registerSelf( registrar, serverIface );
76 }
77 }
78}
79
80
82
84{
85 QgsServiceNativeModuleEntry *entry = findModuleEntry( location );
86 if ( entry )
87 {
88 return entry->mModule;
89 }
90
91 QLibrary lib( location );
92 //QgsDebugMsgLevel( QStringLiteral( "Loading native module %1" ).arg( location ), 2 );
93 qDebug() << QString( "Loading native module %1" ).arg( location );
94 if ( !lib.load() )
95 {
96 QgsMessageLog::logMessage( QString( "Failed to load library %1: %2" ).arg( lib.fileName(), lib.errorString() ) );
97 return nullptr;
98 }
99 // Load entry point
101 entryPointFunc
102 = reinterpret_cast<serviceEntryPoint_t *>( cast_to_fptr( lib.resolve( "QGS_ServiceModule_Init" ) ) );
103
104 if ( entryPointFunc )
105 {
106 QgsServiceModule *module = entryPointFunc();
107 if ( module )
108 {
109 entry = new QgsServiceNativeModuleEntry( location );
110 entry->mModule = module;
111 entry->mUnloadHook = reinterpret_cast<unloadHook_t *>( cast_to_fptr( lib.resolve( "QGS_ServiceModule_Exit" ) ) );
112
113 // Add entry
114 mModules.insert( location, ModuleTable::mapped_type( entry ) );
115 return module;
116 }
117 else
118 {
119 QgsMessageLog::logMessage( QString( "No entry point for module %1" ).arg( lib.fileName() ) );
120 }
121 }
122 else
123 {
124 QgsMessageLog::logMessage( QString( "Error: entry point returned null for %1" ).arg( lib.fileName() ) );
125 }
126
127 // No module found: release library
128 lib.unload();
129 return nullptr;
130}
131
133{
134 ModuleTable::iterator it = mModules.begin();
135 const ModuleTable::iterator end = mModules.end();
136
137 while ( it != end )
138 {
139 unloadModuleEntry( it->get() );
140 ++it;
141 }
142
143 mModules.clear();
144}
145
146QgsServiceNativeModuleEntry *QgsServiceNativeLoader::findModuleEntry( const QString &location )
147{
148 QgsServiceNativeModuleEntry *entry = nullptr;
149 const ModuleTable::iterator item = mModules.find( location );
150 if ( item != mModules.end() )
151 {
152 entry = item->get();
153 }
154 return entry;
155}
156
157void QgsServiceNativeLoader::unloadModuleEntry( QgsServiceNativeModuleEntry *entry )
158{
159 // Call cleanup function if it exists
160 if ( entry->mUnloadHook )
161 {
162 entry->mUnloadHook( entry->mModule );
163 }
164
165 QLibrary lib( entry->mLocation );
166 lib.unload();
167}
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins.
Class defining the service module interface for QGIS server services.
QgsServiceModule * loadNativeModule(const QString &location)
Load the native module from path.
void unloadModules()
Unload all modules.
void loadModules(const QString &modulePath, QgsServiceRegistry &registrar, QgsServerInterface *serverIface=nullptr)
Load all modules from path.
Native module (location, the module itself and the unload function).
QgsServiceNativeModuleEntry(const QString &location)
Constructor for QgsServiceNativeModuleEntry.
QgsServiceRegistry Class defining the registry manager for QGIS server services.
#define cast_to_fptr(f)
Definition qgis.h:5918
void unloadHook_t(QgsServiceModule *)
QgsServiceModule * serviceEntryPoint_t()