26 #if defined (HAVE_CONFIG_H)
35 #if defined (HAVE_DLOPEN_API)
36 # if defined (HAVE_DLFCN_H)
39 extern void * dlopen (
const char *,
int);
40 extern const char * dlerror (
void);
41 extern void * dlsym (
void *,
const char *);
42 extern int dlclose (
void *);
44 #elif defined (HAVE_LOADLIBRARY_API)
45 # define WIN32_LEAN_AND_MEAN 1
57 #if defined (HAVE_LOADLIBRARY_API)
80 : m_count (1), m_fcn_names (), m_file (
f), m_time_loaded (),
81 m_search_all_loaded (false)
86 (*current_liboctave_warning_with_id_handler)
87 (
"Octave:future-time-stamp",
88 "time stamp for file '%s' is in the future",
m_file.c_str ());
94 sys::file_stat fs (m_file);
95 return (fs && fs.is_newer (m_time_loaded));
102 sys::file_stat fs (m_file);
103 if (fs && fs.is_newer (m_time_loaded))
105 m_time_loaded = fs.mtime ();
107 (*current_liboctave_warning_with_id_handler)
108 (
"Octave:library-reload",
109 "library %s not reloaded due to existing references", m_file.c_str ());
117 std::map<std::string, dynlib_rep *>::iterator p = s_instances.find (
f);
118 if (p != s_instances.end ())
126 retval = new_instance (
f);
131 std::list<std::string>
134 std::list<std::string> retval;
136 for (
const auto& p : m_fcn_names)
137 retval.push_back (p.first);
145 auto p = m_fcn_names.find (name);
147 if (p == m_fcn_names.end ())
148 m_fcn_names[name] = 1;
158 auto p = m_fcn_names.find (fcn_name);
160 if (p != m_fcn_names.end () && --(p->second) == 0)
162 m_fcn_names.erase (fcn_name);
169 std::map<std::string, dynamic_library::dynlib_rep *>
174 #if defined (HAVE_DLOPEN_API)
181 octave_dlopen_shlib (
const std::string&
f);
183 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (octave_dlopen_shlib)
185 ~octave_dlopen_shlib ();
187 void *
search (
const std::string& name,
195 bool is_open ()
const
197 return (m_search_all_loaded || m_library !=
nullptr);
205 octave_dlopen_shlib::octave_dlopen_shlib (
const std::string&
f)
214 # if defined (RTLD_NOW)
220 # if defined (RTLD_GLOBAL)
221 flags |= RTLD_GLOBAL;
230 m_library = dlopen (
m_file.c_str (), flags);
234 const char *msg = dlerror ();
237 (*current_liboctave_error_handler)
238 (
"%s: failed to load\nIncompatible version or missing dependency?"
239 "\n%s",
m_file.c_str (), msg);
242 (
"%s: failed to load\nIncompatible version or missing dependency?",
247 octave_dlopen_shlib::~octave_dlopen_shlib ()
254 octave_dlopen_shlib::search (
const std::string& name,
257 void *
function =
nullptr;
260 (*current_liboctave_error_handler)
261 (
"shared library %s is not open", m_file.c_str ());
263 std::string sym_name = name;
266 sym_name = mangler (name);
268 if (m_search_all_loaded)
269 function = dlsym (RTLD_DEFAULT, sym_name.c_str ());
271 function = dlsym (m_library, sym_name.c_str ());
276 #elif defined (HAVE_LOADLIBRARY_API)
283 octave_w32_shlib (
const std::string&
f);
285 OCTAVE_DISABLE_COPY_MOVE (octave_w32_shlib)
287 ~octave_w32_shlib ();
289 void *
search (
const std::string& name,
293 void * global_search (
const std::string& sym_name);
295 bool is_open ()
const
297 return (m_search_all_loaded || m_handle !=
nullptr);
305 octave_w32_shlib::octave_w32_shlib (
const std::string&
f)
316 SetDllDirectoryW (dir.empty ()
317 ?
nullptr : wdir.c_str ());
320 m_handle = LoadLibraryW (wfile.c_str ());
322 SetDllDirectoryW (
nullptr);
326 DWORD last_error = GetLastError ();
328 wchar_t *error_text =
nullptr;
329 FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM |
330 FORMAT_MESSAGE_ALLOCATE_BUFFER |
331 FORMAT_MESSAGE_IGNORE_INSERTS,
333 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
334 reinterpret_cast <wchar_t *
> (&error_text), 0,
nullptr);
336 std::ostringstream err_str;
337 err_str <<
"opening the library '" <<
m_file <<
"' failed (error "
338 << last_error <<
"): ";
339 if (error_text !=
nullptr)
342 LocalFree (error_text);
345 err_str <<
"Unknown error.";
347 (*current_liboctave_error_handler) (
"%s", err_str.str ().c_str ());
351 octave_w32_shlib::~octave_w32_shlib ()
354 FreeLibrary (m_handle);
358 octave_w32_shlib::global_search (
const std::string& sym_name)
360 void *
function =
nullptr;
362 HANDLE proc = GetCurrentProcess ();
365 (*current_liboctave_error_handler)
366 (
"Unable to get handle to own process.");
368 std::size_t lib_num = 64;
369 std::size_t size_lib =
sizeof (HMODULE);
371 DWORD bytes_all_libs;
375 h_libs =
static_cast<HMODULE *
> (
malloc (size_lib*lib_num));
376 got_libs = EnumProcessModules (proc, h_libs, size_lib*lib_num,
379 while (((size_lib*lib_num) < bytes_all_libs) && ii++ < 3)
381 lib_num = bytes_all_libs / size_lib;
382 h_libs =
static_cast<HMODULE *
> (realloc (h_libs, bytes_all_libs));
383 got_libs = EnumProcessModules (proc, h_libs, bytes_all_libs,
389 for (std::size_t i = 0; i < (bytes_all_libs / size_lib); i++)
392 function =
reinterpret_cast<void *
>
393 (GetProcAddress (h_libs[i], sym_name.c_str ()));
407 octave_w32_shlib::search (
const std::string& name,
410 void *
function =
nullptr;
412 if (! m_search_all_loaded && ! is_open ())
413 (*current_liboctave_error_handler)
414 (
"shared library %s is not open", m_file.c_str ());
416 std::string sym_name = name;
419 sym_name = mangler (name);
421 if (m_search_all_loaded)
422 function = global_search (sym_name);
424 function =
reinterpret_cast<void *
> (GetProcAddress (m_handle,
435 #if defined (HAVE_DLOPEN_API)
436 return new octave_dlopen_shlib (
f);
437 #elif defined (HAVE_LOADLIBRARY_API)
438 return new octave_w32_shlib (
f);
440 (*current_liboctave_error_handler)
441 (
"support for dynamically loaded libraries was unavailable or disabled when liboctave was built");
445 OCTAVE_END_NAMESPACE(
octave)
bool remove_fcn_name(const std::string &)
static std::map< std::string, dynlib_rep * > s_instances
void add_fcn_name(const std::string &)
static dynlib_rep * new_instance(const std::string &f)
bool is_out_of_date() const
static dynlib_rep * get_instance(const std::string &f, bool fake)
std::list< std::string > function_names() const
refcount< octave_idx_type > m_count
void * search(const std::string &nm, const name_mangler &mangler=name_mangler()) const
std::function< std::string(const std::string &)> name_mangler
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
std::string dirname(const std::string &path)
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
F77_RET_T const F77_DBLE const F77_DBLE * f
std::string u8_from_wstring(const std::wstring &wchar_string)
std::wstring u8_to_wstring(const std::string &utf8_string)
int release_unreferenced_dynamic_libraries()
std::list< dynamic_library > possibly_unreferenced_dynamic_libraries