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)
78 : m_count (1), m_fcn_names (), m_file (
f), m_time_loaded (),
79 m_search_all_loaded (false)
84 (*current_liboctave_warning_with_id_handler)
85 (
"Octave:warn-future-time-stamp",
86 "timestamp on file %s is in the future",
m_file.c_str ());
92 sys::file_stat fs (m_file);
93 return (fs && fs.is_newer (m_time_loaded));
100 sys::file_stat fs (m_file);
101 if (fs && fs.is_newer (m_time_loaded))
103 m_time_loaded = fs.mtime ();
105 (*current_liboctave_warning_with_id_handler)
106 (
"Octave:library-reload",
107 "library %s not reloaded due to existing references", m_file.c_str ());
115 std::map<std::string, dynlib_rep *>::iterator p = s_instances.find (
f);
116 if (p != s_instances.end ())
124 retval = new_instance (
f);
129 std::list<std::string>
132 std::list<std::string> retval;
134 for (
const auto& p : m_fcn_names)
135 retval.push_back (p.first);
143 auto p = m_fcn_names.find (name);
145 if (p == m_fcn_names.end ())
146 m_fcn_names[name] = 1;
156 auto p = m_fcn_names.find (fcn_name);
158 if (p != m_fcn_names.end () && --(p->second) == 0)
160 m_fcn_names.erase (fcn_name);
167 std::map<std::string, dynamic_library::dynlib_rep *>
172 #if defined (HAVE_DLOPEN_API)
179 octave_dlopen_shlib (
const std::string&
f);
183 octave_dlopen_shlib (
const octave_dlopen_shlib&) =
delete;
185 octave_dlopen_shlib&
operator = (
const octave_dlopen_shlib&) =
delete;
187 ~octave_dlopen_shlib (
void);
189 void *
search (
const std::string& name,
197 bool is_open (
void)
const
199 return (m_search_all_loaded || m_library !=
nullptr);
207 octave_dlopen_shlib::octave_dlopen_shlib (
const std::string&
f)
216 # if defined (RTLD_NOW)
222 # if defined (RTLD_GLOBAL)
223 flags |= RTLD_GLOBAL;
232 m_library = dlopen (
m_file.c_str (), flags);
236 const char *msg = dlerror ();
239 (*current_liboctave_error_handler)
240 (
"%s: failed to load\nIncompatible version or missing dependency?"
241 "\n%s",
m_file.c_str (), msg);
244 (
"%s: failed to load\nIncompatible version or missing dependency?",
249 octave_dlopen_shlib::~octave_dlopen_shlib (
void)
259 void *
function =
nullptr;
262 (*current_liboctave_error_handler)
263 (
"shared library %s is not open", m_file.c_str ());
265 std::string sym_name = name;
268 sym_name = mangler (name);
270 if (m_search_all_loaded)
271 function = dlsym (RTLD_DEFAULT, sym_name.c_str ());
273 function = dlsym (m_library, sym_name.c_str ());
278 #elif defined (HAVE_LOADLIBRARY_API)
285 octave_w32_shlib (
const std::string&
f);
289 octave_w32_shlib (
const octave_w32_shlib&) =
delete;
291 octave_w32_shlib&
operator = (
const octave_w32_shlib&) =
delete;
293 ~octave_w32_shlib (
void);
295 void *
search (
const std::string& name,
299 void * global_search (
const std::string& sym_name);
301 bool is_open (
void)
const
303 return (m_search_all_loaded || m_handle !=
nullptr);
311 octave_w32_shlib::octave_w32_shlib (
const std::string&
f)
322 SetDllDirectoryW (dir.empty ()
323 ?
nullptr : wdir.c_str ());
326 m_handle = LoadLibraryW (wfile.c_str ());
328 SetDllDirectoryW (
nullptr);
332 DWORD last_error = GetLastError ();
334 wchar_t *error_text =
nullptr;
335 FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM |
336 FORMAT_MESSAGE_ALLOCATE_BUFFER |
337 FORMAT_MESSAGE_IGNORE_INSERTS,
339 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
340 reinterpret_cast <wchar_t *
> (&error_text), 0,
nullptr);
342 std::ostringstream err_str;
343 err_str <<
"opening the library '" <<
m_file <<
"' failed (error "
344 << last_error <<
"): ";
345 if (error_text !=
nullptr)
348 LocalFree (error_text);
351 err_str <<
"Unknown error.";
353 (*current_liboctave_error_handler) (
"%s", err_str.str ().c_str ());
357 octave_w32_shlib::~octave_w32_shlib (
void)
360 FreeLibrary (m_handle);
364 octave_w32_shlib::global_search (
const std::string& sym_name)
366 void *
function =
nullptr;
368 HANDLE proc = GetCurrentProcess ();
371 (*current_liboctave_error_handler)
372 (
"Unable to get handle to own process.");
374 std::size_t lib_num = 64;
375 std::size_t size_lib =
sizeof (HMODULE);
377 DWORD bytes_all_libs;
381 h_libs =
static_cast<HMODULE *
> (
malloc (size_lib*lib_num));
382 got_libs = EnumProcessModules (proc, h_libs, size_lib*lib_num,
385 while (((size_lib*lib_num) < bytes_all_libs) && ii++ < 3)
387 lib_num = bytes_all_libs / size_lib;
388 h_libs =
static_cast<HMODULE *
> (realloc (h_libs, bytes_all_libs));
389 got_libs = EnumProcessModules (proc, h_libs, bytes_all_libs,
395 for (std::size_t i = 0; i < (bytes_all_libs / size_lib); i++)
398 function =
reinterpret_cast<void *
>
399 (GetProcAddress (h_libs[i], sym_name.c_str ()));
416 void *
function =
nullptr;
418 if (! m_search_all_loaded && ! is_open ())
419 (*current_liboctave_error_handler)
420 (
"shared library %s is not open", m_file.c_str ());
422 std::string sym_name = name;
425 sym_name = mangler (name);
427 if (m_search_all_loaded)
428 function = global_search (sym_name);
430 function =
reinterpret_cast<void *
> (GetProcAddress (m_handle,
441 #if defined (HAVE_DLOPEN_API)
442 return new octave_dlopen_shlib (
f);
443 #elif defined (HAVE_LOADLIBRARY_API)
444 return new octave_w32_shlib (
f);
446 (*current_liboctave_error_handler)
447 (
"support for dynamically loaded libraries was unavailable or disabled when liboctave was built");
OCTAVE_API bool remove_fcn_name(const std::string &)
static OCTAVE_API std::map< std::string, dynlib_rep * > s_instances
OCTAVE_API void add_fcn_name(const std::string &)
static OCTAVE_API dynlib_rep * new_instance(const std::string &f)
static OCTAVE_API dynlib_rep * get_instance(const std::string &f, bool fake)
OCTAVE_API std::list< std::string > function_names(void) const
OCTAVE_API void fake_reload(void)
refcount< octave_idx_type > m_count
OCTAVE_API bool is_out_of_date(void) const
void * search(const std::string &nm, const name_mangler &mangler=name_mangler()) const
std::function< std::string(const std::string &)> name_mangler
dynamic_library & operator=(const dynamic_library &sl)
static OCTAVE_API dynlib_rep s_nil_rep
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
std::string dirname(const std::string &path)
static std::list< std::string > search(const std::string &path, const std::string &original_name, bool all)
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)
std::list< dynamic_library > possibly_unreferenced_dynamic_libraries
int release_unreferenced_dynamic_libraries(void)