Arcane  v3.16.7.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
GlibDynamicLibraryLoader.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* GlibDynamicLibraryLoader.cc (C) 2000-2025 */
9/* */
10/* Chargeur dynamique de bibliothèque avec Glib (utiliser gmodule). */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/String.h"
15#include "arcane/utils/PlatformUtils.h"
16#include "arcane/utils/ArrayView.h"
17#include "arcane/utils/IDynamicLibraryLoader.h"
18
19#include "gmodule.h"
20
21#include <iostream>
22#include <set>
23#include <vector>
24
25/*---------------------------------------------------------------------------*/
26/*---------------------------------------------------------------------------*/
27
28namespace Arcane
29{
30
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36class ARCANE_IMPL_EXPORT GlibDynamicLibrary
37: public IDynamicLibrary
38{
39 public:
40 GlibDynamicLibrary(GlibDynamicLibraryLoader* mng,GModule* gmodule)
41 : m_manager(mng), m_gmodule(gmodule){}
42 public:
43 void close() override;
44 void* getSymbolAddress(const String& symbol_name,bool* is_found) override;
45 private:
46 GlibDynamicLibraryLoader* m_manager;
47 GModule* m_gmodule;
48};
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
55class ARCANE_IMPL_EXPORT GlibDynamicLibraryLoader
57{
58 public:
59 GlibDynamicLibraryLoader() : m_is_verbose(false){}
61
62 public:
63
64 void build() override
65 {
66 String s = platform::getEnvironmentVariable("ARCANE_VERBOSE_DYNAMICLIBRARY");
67 if (s=="1" || s=="true")
68 m_is_verbose = true;
69 }
70
71 IDynamicLibrary* open(const String& directory,const String& name) override
72 {
73 IDynamicLibrary* dl = _tryOpen(directory, name);
74 if (!dl){
75 // Si on ne trouve pas, essaie avec l'extension '.dll' ou '.dylib' car sous
76 // windows ou macos, certaines version de la GLIB prefixent automatiquement le
77 // nom de la bibliothèque par 'lib' si elle ne finit pas par '.dll' ou '.dylib'.
78#ifdef ARCANE_OS_WIN32
79 dl = _tryOpen(directory, name + ".dll");
80#endif
81#ifdef ARCANE_OS_MACOS
82 dl = _tryOpen(directory, "lib" + name + ".dylib");
83#endif
84 }
85 if (!dl){
86 // Si on ne trouve pas, essaie en cherchant à côté du binaire
87 dl = _tryOpen(".", name);
88 }
89 if (!dl){
90 // Si on ne trouve pas, essaie en cherchant à côté du binaire
91 // et avec l'extension dll ou dylib
92#ifdef ARCANE_OS_WIN32
93 dl = _tryOpen(".", name + ".dll");
94#endif
95#ifdef ARCANE_OS_MACOS
96 dl = _tryOpen(".", "lib" + name + ".dylib");
97#endif
98 }
99 return dl;
100 }
101
102 IDynamicLibrary* _tryOpen(const String& directory, const String& name)
103 {
104 const gchar* gdirectory = reinterpret_cast<const gchar*>(directory.utf8().data());
105 const gchar* gname = reinterpret_cast<const gchar*>(name.utf8().data());
106 gchar* full_path = g_module_build_path(gdirectory, gname);
107 if (m_is_verbose) {
108 std::cout << "** Load Dynamic Library '" << full_path << "'...";
109 }
110 GModule* gmodule = g_module_open(full_path, GModuleFlags());
111 g_free(full_path);
112 if (m_is_verbose) {
113 if (!gmodule){
114 std::cout << " NOT FOUND\n";
115 } else {
116 std::cout << " OK\n";
117 }
118 }
119 if (!gmodule)
120 return nullptr;
121 auto lib = new GlibDynamicLibrary(this,gmodule);
122 m_opened_libraries.insert(lib);
123 return lib;
124 }
125
126 void closeLibraries() override
127 {
128 // Cette méthode va modifier m opened libraries donc il faut le copier avant.
129 std::vector<GlibDynamicLibrary*> libs(m_opened_libraries.begin(),m_opened_libraries.end());
130 for( auto lib : libs ){
131 lib->close();
132 delete lib;
133 }
134 }
135
136 void removeInstance(GlibDynamicLibrary* lib)
137 {
138 auto iter = m_opened_libraries.find(lib);
139 if (iter!=m_opened_libraries.end())
140 m_opened_libraries.erase(iter);
141 }
142
143 private:
144
145 bool m_is_verbose;
146 std::set<GlibDynamicLibrary*> m_opened_libraries;
147};
148
149/*---------------------------------------------------------------------------*/
150/*---------------------------------------------------------------------------*/
151
153close()
154{
155 if (!m_gmodule)
156 return;
157 bool is_ok = g_module_close(m_gmodule);
158 m_gmodule = 0;
159 if (!is_ok)
160 std::cerr << "WARNING: can not unload module\n";
161 m_manager->removeInstance(this);
162}
163
164/*---------------------------------------------------------------------------*/
165/*---------------------------------------------------------------------------*/
166
168getSymbolAddress(const String& symbol_name,bool* is_found)
169{
170 if (is_found)
171 *is_found = false;
172 if (!m_gmodule)
173 return nullptr;
174 const gchar* gname = reinterpret_cast<const gchar*>(symbol_name.utf8().data());
175 void* symbol_addr = nullptr;
176 bool r = ::g_module_symbol(m_gmodule,gname,&symbol_addr);
177 if (is_found)
178 (*is_found) = r;
179 return symbol_addr;
180}
181
182/*---------------------------------------------------------------------------*/
183/*---------------------------------------------------------------------------*/
184
185extern "C++" ARCANE_IMPL_EXPORT IDynamicLibraryLoader*
186createGlibDynamicLibraryLoader()
187{
189 idll->build();
190 return idll;
191}
192
193/*---------------------------------------------------------------------------*/
194/*---------------------------------------------------------------------------*/
195
196} // End namespace Arcane
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
200
Interface d'une chargeur dynamique de bibliothèque.
IDynamicLibrary * open(const String &directory, const String &name) override
Charge une bibliothèque dynamique.
virtual ~GlibDynamicLibraryLoader()
Libère les ressources.
void closeLibraries() override
Ferme toutes les bibliothèques ouvertes via open()
void close() override
Ferme la bibliothèque dynamique.
void * getSymbolAddress(const String &symbol_name, bool *is_found) override
Retourne l'adresse du symbol de nom symbol_name.
Interface d'une chargeur dynamique de bibliothèque.
Interface d'une bibliothèque dynamique.
Chaîne de caractères unicode.
ByteConstArrayView utf8() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:276
ARCCORE_BASE_EXPORT String getEnvironmentVariable(const String &name)
Variable d'environnement du nom name.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-