24 #if defined (HAVE_CONFIG_H) 30 #if defined (HAVE_SHL_LOAD_API) 35 #if defined (HAVE_DYLD_API) 36 # include <mach-o/dyld.h> 41 #if defined (HAVE_DLOPEN_API) 42 # if defined (HAVE_DLFCN_H) 45 extern void * dlopen (
const char *,
int);
46 extern const char * dlerror (
void);
47 extern void * dlsym (
void *,
const char *);
48 extern int dlclose (
void *);
50 #elif defined (HAVE_SHL_LOAD_API) 52 #elif defined (HAVE_LOADLIBRARY_API) 53 # define WIN32_LEAN_AND_MEAN 1 68 : count (1),
file (
f), tm_loaded (), fcn_names (), search_all_loaded (
false)
73 (*current_liboctave_warning_with_id_handler)
74 (
"Octave:warn-future-time-stamp",
75 "timestamp on file %s is in the future",
file.c_str ());
94 (*current_liboctave_warning_with_id_handler)
95 (
"Octave:library-reload",
96 "library %s not reloaded due to existing references",
file.c_str ());
104 std::map<std::string, dynlib_rep *>::iterator
p = instances.find (
f);
105 if (
p != instances.end ())
118 std::list<std::string>
121 std::list<std::string>
retval;
123 for (
const auto&
p : fcn_names)
132 auto p = fcn_names.find (
name);
134 if (
p == fcn_names.end ())
145 auto p = fcn_names.find (fcn_name);
147 if (
p != fcn_names.end () && --(
p->second) == 0)
149 fcn_names.erase (fcn_name);
156 std::map<std::string, dynamic_library::dynlib_rep *>
161 #if defined (HAVE_DLOPEN_API) 172 octave_dlopen_shlib (
const octave_dlopen_shlib&) =
delete;
174 octave_dlopen_shlib&
operator = (
const octave_dlopen_shlib&) =
delete;
176 ~octave_dlopen_shlib (
void);
185 bool is_open (
void)
const 187 return (search_all_loaded || library !=
nullptr);
195 octave_dlopen_shlib::octave_dlopen_shlib (
const std::string&
f)
204 # if defined (RTLD_NOW) 210 # if defined (RTLD_GLOBAL) 211 flags |= RTLD_GLOBAL;
220 library = dlopen (
file.c_str (), flags);
224 const char *msg = dlerror ();
227 (*current_liboctave_error_handler) (
"%s: failed to load: %s",
235 octave_dlopen_shlib::~octave_dlopen_shlib (
void)
245 void *
function =
nullptr;
248 (*current_liboctave_error_handler)
249 (
"shared library %s is not open",
file.c_str ());
254 sym_name = mangler (
name);
256 if (search_all_loaded)
257 function = dlsym (RTLD_DEFAULT, sym_name.c_str ());
259 function = dlsym (library, sym_name.c_str ());
264 #elif defined (HAVE_SHL_LOAD_API) 267 octave_shl_load_shlib :
public dynamic_library::dynlib_rep
275 octave_shl_load_shlib (
const octave_shl_load_shlib&) =
delete;
277 octave_shl_load_shlib&
operator = (
const octave_shl_load_shlib&) =
delete;
279 ~octave_shl_load_shlib (
void);
284 bool is_open (
void)
const {
return (search_all_loaded || library != 0); }
291 octave_shl_load_shlib::octave_shl_load_shlib (
const std::string&
f)
302 library = shl_load (
file.c_str (), BIND_IMMEDIATE, 0L);
307 (*current_liboctave_error_handler) (
"%s", std::strerror (errno));
311 octave_shl_load_shlib::~octave_shl_load_shlib (
void)
314 shl_unload (library);
321 void *
function =
nullptr;
324 (*current_liboctave_error_handler)
325 (
"shared library %s is not open",
file.c_str ());
330 sym_name = mangler (
name);
333 int status = shl_findsym (
nullptr, sym_name.c_str (),
334 TYPE_UNDEFINED, &
function);
336 int status = shl_findsym (&library, sym_name.c_str (),
337 TYPE_UNDEFINED, &
function);
342 #elif defined (HAVE_LOADLIBRARY_API) 345 octave_w32_shlib:
public dynamic_library::dynlib_rep
353 octave_w32_shlib (
const octave_w32_shlib&) =
delete;
355 octave_w32_shlib&
operator = (
const octave_w32_shlib&) =
delete;
357 ~octave_w32_shlib (
void);
362 void * global_search (
const std::string& sym_name);
374 SetDllDirectory (dir.empty () ? nullptr : dir.c_str ());
377 octave_w32_shlib::octave_w32_shlib (
const std::string&
f)
388 set_dll_directory (dir);
392 set_dll_directory ();
396 DWORD lastError = GetLastError ();
401 case ERROR_MOD_NOT_FOUND:
402 case ERROR_DLL_NOT_FOUND:
403 msg =
"could not find library or dependencies";
406 case ERROR_INVALID_DLL:
407 msg =
"library or its dependencies are damaged";
410 case ERROR_DLL_INIT_FAILED:
411 msg =
"library initialization routine failed";
415 msg =
"library open failed";
418 (*current_liboctave_error_handler) (
"%s: %s", msg,
file.c_str ());
422 octave_w32_shlib::~octave_w32_shlib (
void)
429 octave_w32_shlib::global_search (
const std::string& sym_name)
431 void *
function =
nullptr;
433 HANDLE proc = GetCurrentProcess ();
436 (*current_liboctave_error_handler)
437 (
"Unable to get handle to own process.");
440 size_t size_lib =
sizeof (HMODULE);
442 DWORD bytes_all_libs;
446 h_libs =
static_cast<HMODULE *
> (malloc (size_lib*lib_num));
447 got_libs = EnumProcessModules (proc, h_libs, size_lib*lib_num,
450 while (((size_lib*lib_num) < bytes_all_libs) && ii++ < 3)
452 lib_num = bytes_all_libs / size_lib;
453 h_libs =
static_cast<HMODULE *
> (realloc (h_libs, bytes_all_libs));
454 got_libs = EnumProcessModules (proc, h_libs, bytes_all_libs,
460 for (
size_t i = 0;
i < (bytes_all_libs / size_lib);
i++)
463 function =
reinterpret_cast<void *
> 464 (GetProcAddress (h_libs[
i], sym_name.c_str ()));
481 void *
function =
nullptr;
483 if (! search_all_loaded && ! is_open ())
484 (*current_liboctave_error_handler)
485 (
"shared library %s is not open",
file.c_str ());
490 sym_name = mangler (
name);
492 if (search_all_loaded)
493 function = global_search (sym_name);
495 function =
reinterpret_cast<void *
> (GetProcAddress (
handle,
501 #elif defined (HAVE_DYLD_API) 504 octave_dyld_shlib :
public dynamic_library::dynlib_rep
508 octave_dyld_shlib (
void);
512 octave_dyld_shlib (
const octave_dyld_shlib&) =
delete;
514 octave_dyld_shlib&
operator = (
const octave_dyld_shlib&) =
delete;
516 ~octave_dyld_shlib (
void);
525 bool is_open (
void)
const {
return (search_all_loaded ||
handle != 0); }
529 NSObjectFileImage img;
533 octave_dyld_shlib::octave_dyld_shlib (
const std::string&
f)
538 (
"global search is not implemented for DYLD_API");
540 int returnCode = NSCreateObjectFileImageFromFile (
file.c_str (), &img);
542 if (NSObjectFileImageSuccess != returnCode)
544 (*current_liboctave_error_handler)
545 (
"got NSObjectFileImageReturnCode %d", returnCode);
552 (NSLINKMODULE_OPTION_RETURN_ON_ERROR
553 | NSLINKMODULE_OPTION_PRIVATE));
556 NSLinkEditErrors ler;
559 const char *errstr =
nullptr;
561 NSLinkEditError (&ler, &lerno, &file2, &errstr);
564 errstr =
"unspecified error";
566 (*current_liboctave_error_handler) (
"%s: %s",
file.c_str (), errstr);
570 octave_dyld_shlib::~octave_dyld_shlib (
void)
573 NSUnLinkModule (
handle, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
575 NSDestroyObjectFileImage (img);
582 void *
function =
nullptr;
585 (*current_liboctave_error_handler)
586 (
"bundle %s is not open",
file.c_str ());
591 sym_name = mangler (
name);
593 NSSymbol symbol = NSLookupSymbolInModule (
handle, sym_name.c_str ());
597 function = NSAddressOfSymbol (symbol);
605 dynamic_library::dynlib_rep *
608 #if defined (HAVE_DLOPEN_API) 609 return new octave_dlopen_shlib (
f);
610 #elif defined (HAVE_SHL_LOAD_API) 611 return new octave_shl_load_shlib (
f);
612 #elif defined (HAVE_LOADLIBRARY_API) 613 return new octave_w32_shlib (
f);
614 #elif defined (HAVE_DYLD_API) 615 return new octave_dyld_shlib (
f);
617 (*current_liboctave_error_handler)
618 (
"support for dynamically loaded libraries was unavailable or disabled when liboctave was built");
For example cd octave end example noindent changes the current working directory to file
virtual bool is_open(void) const
std::list< std::string > function_names(void) const
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE * f
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
static std::map< std::string, dynlib_rep * > instances
std::string dirname(const std::string &path)
std::list< std::string > close(void)
void add_fcn_name(const std::string &)
virtual void * search(const std::string &, name_mangler=nullptr)
nd deftypefn *std::string name
static std::list< std::string > search(const std::string &path, const std::string &original_name, bool all)
static dynlib_rep nil_rep
std::string(* name_mangler)(const std::string &)
void open(const std::string &f)
octave::sys::file_stat fs(filename)
bool remove_fcn_name(const std::string &)
static dynlib_rep * get_instance(const std::string &f, bool fake)
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
sys::time mtime(void) const
void * search(const std::string &nm, name_mangler mangler=nullptr) const
bool is_newer(const sys::time &time) const
dynamic_library & operator=(const dynamic_library &sl)
static dynlib_rep * new_instance(const std::string &f)
bool is_out_of_date(void) const