26 #if defined (HAVE_CONFIG_H)
34 #if defined (HAVE_DLOPEN_API)
35 # if defined (HAVE_DLFCN_H)
38 extern void * dlopen (
const char *,
int);
39 extern const char * dlerror (
void);
40 extern void * dlsym (
void *,
const char *);
41 extern int dlclose (
void *);
43 #elif defined (HAVE_LOADLIBRARY_API)
44 # define WIN32_LEAN_AND_MEAN 1
56 #if defined (HAVE_LOADLIBRARY_API)
63 : m_count (1), m_fcn_names (), m_file (
f), m_time_loaded (),
64 m_search_all_loaded (false)
69 (*current_liboctave_warning_with_id_handler)
70 (
"Octave:warn-future-time-stamp",
71 "timestamp on file %s is in the future",
m_file.c_str ());
78 return (fs && fs.
is_newer (m_time_loaded));
86 if (fs && fs.
is_newer (m_time_loaded))
88 m_time_loaded = fs.
mtime ();
90 (*current_liboctave_warning_with_id_handler)
91 (
"Octave:library-reload",
92 "library %s not reloaded due to existing references", m_file.c_str ());
100 std::map<std::string, dynlib_rep *>::iterator p = s_instances.
find (
f);
101 if (p != s_instances.end ())
114 std::list<std::string>
117 std::list<std::string>
retval;
119 for (
const auto& p : m_fcn_names)
120 retval.push_back (p.first);
128 auto p = m_fcn_names.find (
name);
130 if (p == m_fcn_names.end ())
131 m_fcn_names[
name] = 1;
141 auto p = m_fcn_names.
find (fcn_name);
143 if (p != m_fcn_names.end () && --(p->second) == 0)
145 m_fcn_names.erase (fcn_name);
152 std::map<std::string, dynamic_library::dynlib_rep *>
157 #if defined (HAVE_DLOPEN_API)
164 octave_dlopen_shlib (
const std::string&
f);
168 octave_dlopen_shlib (
const octave_dlopen_shlib&) =
delete;
170 octave_dlopen_shlib&
operator = (
const octave_dlopen_shlib&) =
delete;
172 ~octave_dlopen_shlib (
void);
182 bool is_open (
void)
const
184 return (m_search_all_loaded || m_library !=
nullptr);
192 octave_dlopen_shlib::octave_dlopen_shlib (
const std::string&
f)
201 # if defined (RTLD_NOW)
207 # if defined (RTLD_GLOBAL)
208 flags |= RTLD_GLOBAL;
217 m_library = dlopen (
m_file.c_str (), flags);
221 const char *msg = dlerror ();
224 (*current_liboctave_error_handler) (
"%s: failed to load: %s",
232 octave_dlopen_shlib::~octave_dlopen_shlib (
void)
242 void *
function =
nullptr;
245 (*current_liboctave_error_handler)
246 (
"shared library %s is not open", m_file.c_str ());
248 std::string sym_name =
name;
251 sym_name = mangler (
name);
253 if (m_search_all_loaded)
254 function = dlsym (RTLD_DEFAULT, sym_name.c_str ());
256 function = dlsym (m_library, sym_name.c_str ());
261 #elif defined (HAVE_LOADLIBRARY_API)
264 octave_w32_shlib:
public dynamic_library::dynlib_rep
268 octave_w32_shlib (
const std::string&
f);
272 octave_w32_shlib (
const octave_w32_shlib&) =
delete;
274 octave_w32_shlib&
operator = (
const octave_w32_shlib&) =
delete;
276 ~octave_w32_shlib (
void);
282 void * global_search (
const std::string& sym_name);
284 bool is_open (
void)
const
286 return (m_search_all_loaded || m_handle !=
nullptr);
294 octave_w32_shlib::octave_w32_shlib (
const std::string&
f)
305 SetDllDirectoryW (dir.empty ()
306 ?
nullptr : wdir.c_str ());
309 m_handle = LoadLibraryW (wfile.c_str ());
311 SetDllDirectoryW (
nullptr);
315 DWORD last_error = GetLastError ();
317 wchar_t *error_text =
nullptr;
318 FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM |
319 FORMAT_MESSAGE_ALLOCATE_BUFFER |
320 FORMAT_MESSAGE_IGNORE_INSERTS,
322 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
323 reinterpret_cast <wchar_t *
> (&error_text), 0,
nullptr);
325 std::ostringstream err_str;
326 err_str <<
"opening the library '" <<
m_file <<
"' failed (error "
327 << last_error <<
"): ";
328 if (error_text !=
nullptr)
331 LocalFree (error_text);
334 err_str <<
"Unknown error.";
336 (*current_liboctave_error_handler) (
"%s", err_str.str ().c_str ());
340 octave_w32_shlib::~octave_w32_shlib (
void)
343 FreeLibrary (m_handle);
347 octave_w32_shlib::global_search (
const std::string& sym_name)
349 void *
function =
nullptr;
351 HANDLE proc = GetCurrentProcess ();
354 (*current_liboctave_error_handler)
355 (
"Unable to get handle to own process.");
358 size_t size_lib =
sizeof (HMODULE);
360 DWORD bytes_all_libs;
364 h_libs =
static_cast<HMODULE *
> (
malloc (size_lib*lib_num));
365 got_libs = EnumProcessModules (proc, h_libs, size_lib*lib_num,
368 while (((size_lib*lib_num) < bytes_all_libs) && ii++ < 3)
370 lib_num = bytes_all_libs / size_lib;
371 h_libs =
static_cast<HMODULE *
> (realloc (h_libs, bytes_all_libs));
372 got_libs = EnumProcessModules (proc, h_libs, bytes_all_libs,
378 for (
size_t i = 0; i < (bytes_all_libs / size_lib); i++)
381 function =
reinterpret_cast<void *
>
382 (GetProcAddress (h_libs[i], sym_name.c_str ()));
399 void *
function =
nullptr;
401 if (! m_search_all_loaded && ! is_open ())
402 (*current_liboctave_error_handler)
403 (
"shared library %s is not open", m_file.c_str ());
405 std::string sym_name =
name;
408 sym_name = mangler (
name);
410 if (m_search_all_loaded)
411 function = global_search (sym_name);
413 function =
reinterpret_cast<void *
> (GetProcAddress (m_handle,
421 dynamic_library::dynlib_rep *
424 #if defined (HAVE_DLOPEN_API)
425 return new octave_dlopen_shlib (
f);
426 #elif defined (HAVE_LOADLIBRARY_API)
427 return new octave_w32_shlib (
f);
429 (*current_liboctave_error_handler)
430 (
"support for dynamically loaded libraries was unavailable or disabled when liboctave was built");
Array< octave_idx_type > find(octave_idx_type n=-1, bool backward=false) const
Find indices of (at most n) nonzero elements.
bool remove_fcn_name(const std::string &)
static std::map< std::string, dynlib_rep * > s_instances
std::list< std::string > function_names(void) const
static dynlib_rep * new_instance(const std::string &f)
bool is_out_of_date(void) const
void add_fcn_name(const std::string &)
static dynlib_rep * get_instance(const std::string &f, bool fake)
std::function< std::string(const std::string &)> name_mangler
static dynlib_rep s_nil_rep
void * search(const std::string &nm, const name_mangler &mangler=name_mangler()) const
dynamic_library & operator=(const dynamic_library &sl)
sys::time mtime(void) const
bool is_newer(const sys::time &time) const
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
std::string dirname(const std::string &path)
std::string u8_from_wstring(const std::wstring &wchar_string)
std::wstring u8_to_wstring(const std::string &utf8_string)
static double f(double k, double l_nu, double c_pm)
octave_value::octave_value(const Array< char > &chm, char type) return retval