Arcane  v4.1.1.0
Documentation utilisateur
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 (utilise gmodule). */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arccore/base/String.h"
15#include "arccore/base/PlatformUtils.h"
17#include "arccore/base/internal/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 GlibDynamicLibrary
37: public IDynamicLibrary
38{
39 public:
40
41 GlibDynamicLibrary(GlibDynamicLibraryLoader* mng, GModule* gmodule)
42 : m_manager(mng)
43 , m_gmodule(gmodule)
44 {}
45
46 public:
47
48 void close() override;
49 void* getSymbolAddress(const String& symbol_name, bool* is_found) override;
50
51 private:
52
53 GlibDynamicLibraryLoader* m_manager = nullptr;
54 GModule* m_gmodule = nullptr;
55};
56
57/*---------------------------------------------------------------------------*/
58/*---------------------------------------------------------------------------*/
59/*!
60 * \brief Interface d'une chargeur dynamique de bibliothèque.
61 */
62class GlibDynamicLibraryLoader
63: public IDynamicLibraryLoader
64{
65 public:
66
67 GlibDynamicLibraryLoader()
68 {
69 String s = platform::getEnvironmentVariable("ARCANE_VERBOSE_DYNAMICLIBRARY");
70 if (s == "1" || s == "true")
71 m_is_verbose = true;
72 }
73
74 void build() override {}
75
76 IDynamicLibrary* open(const String& directory, const String& name) override
77 {
78 IDynamicLibrary* dl = _tryOpen(directory, name);
79 if (!dl) {
80 // Si on ne trouve pas, essaie avec l'extension '.dll' ou '.dylib' car sous
81 // windows ou macos, certaines version de la GLIB prefixent automatiquement le
82 // nom de la bibliothèque par 'lib' si elle ne finit pas par '.dll' ou '.dylib'.
83#ifdef ARCCORE_OS_WIN32
84 dl = _tryOpen(directory, name + ".dll");
85#endif
86#ifdef ARCCORE_OS_MACOS
87 dl = _tryOpen(directory, "lib" + name + ".dylib");
88#endif
89 }
90 if (!dl) {
91 // Si on ne trouve pas, essaie en cherchant à côté du binaire
92 dl = _tryOpen(".", name);
93 }
94 if (!dl) {
95 // Si on ne trouve pas, essaie en cherchant à côté du binaire
96 // et avec l'extension dll ou dylib
97#ifdef ARCCORE_OS_WIN32
98 dl = _tryOpen(".", name + ".dll");
99#endif
100#ifdef ARCCORE_OS_MACOS
101 dl = _tryOpen(".", "lib" + name + ".dylib");
102#endif
103 }
104 return dl;
105 }
106
107 IDynamicLibrary* _tryOpen(const String& directory, const String& name)
108 {
109 const gchar* gdirectory = reinterpret_cast<const gchar*>(directory.utf8().data());
110 const gchar* gname = reinterpret_cast<const gchar*>(name.utf8().data());
111 gchar* full_path = g_module_build_path(gdirectory, gname);
112 if (m_is_verbose) {
113 std::cout << "** Load Dynamic Library '" << full_path << "'...";
114 }
115 GModule* gmodule = g_module_open(full_path, GModuleFlags());
116 g_free(full_path);
117 if (m_is_verbose) {
118 if (!gmodule) {
119 std::cout << " NOT FOUND\n";
120 }
121 else {
122 std::cout << " OK\n";
123 }
124 }
125 if (!gmodule)
126 return nullptr;
127 auto lib = new GlibDynamicLibrary(this, gmodule);
128 m_opened_libraries.insert(lib);
129 return lib;
130 }
131
132 void closeLibraries() override
133 {
134 // Cette méthode va modifier m opened libraries donc il faut le copier avant.
135 std::vector<GlibDynamicLibrary*> libs(m_opened_libraries.begin(), m_opened_libraries.end());
136 for (auto lib : libs) {
137 lib->close();
138 delete lib;
139 }
140 }
141
142 void removeInstance(GlibDynamicLibrary* lib)
143 {
144 auto iter = m_opened_libraries.find(lib);
145 if (iter != m_opened_libraries.end())
146 m_opened_libraries.erase(iter);
147 }
148
149 private:
150
151 bool m_is_verbose = false;
152 std::set<GlibDynamicLibrary*> m_opened_libraries;
153};
154
155/*---------------------------------------------------------------------------*/
156/*---------------------------------------------------------------------------*/
157
158void GlibDynamicLibrary::
159close()
160{
161 if (!m_gmodule)
162 return;
163 bool is_ok = g_module_close(m_gmodule);
164 m_gmodule = 0;
165 if (!is_ok)
166 std::cerr << "WARNING: can not unload module\n";
167 m_manager->removeInstance(this);
168}
169
170/*---------------------------------------------------------------------------*/
171/*---------------------------------------------------------------------------*/
172
173void* GlibDynamicLibrary::
174getSymbolAddress(const String& symbol_name, bool* is_found)
175{
176 if (is_found)
177 *is_found = false;
178 if (!m_gmodule)
179 return nullptr;
180 const gchar* gname = reinterpret_cast<const gchar*>(symbol_name.utf8().data());
181 void* symbol_addr = nullptr;
182 bool r = ::g_module_symbol(m_gmodule, gname, &symbol_addr);
183 if (is_found)
184 (*is_found) = r;
185 return symbol_addr;
186}
187
188/*---------------------------------------------------------------------------*/
189/*---------------------------------------------------------------------------*/
190
191extern "C++" ARCCORE_BASE_EXPORT IDynamicLibraryLoader*
192createGlibDynamicLibraryLoader()
193{
194 IDynamicLibraryLoader* idll = new GlibDynamicLibraryLoader();
195 idll->build();
196 return idll;
197}
198
199/*---------------------------------------------------------------------------*/
200/*---------------------------------------------------------------------------*/
201namespace
202{
203 GlibDynamicLibraryLoader glib_dynamic_loader;
204 IDynamicLibraryLoader* global_default_loader = &glib_dynamic_loader;
205}
206
207IDynamicLibraryLoader* IDynamicLibraryLoader::getDefault()
208{
209 return global_default_loader;
210}
211
212/*---------------------------------------------------------------------------*/
213/*---------------------------------------------------------------------------*/
214
215} // namespace Arcane
216
217/*---------------------------------------------------------------------------*/
218/*---------------------------------------------------------------------------*/
Types et fonctions associés aux classes ArrayView et ConstArrayView.
Interface d'une chargeur dynamique de bibliothèque.
Chaîne de caractères unicode.
ByteConstArrayView utf8() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:276
String getEnvironmentVariable(const String &name)
Variable d'environnement du nom name.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-