/src/wrappers/posix/dynamic-linking/library/dynamic_shared_object.e

http://github.com/tybor/Liberty · Specman e · 130 lines · 48 code · 19 blank · 63 comment · 2 complexity · dbbad3952097080691a09eb05a3dec3d MD5 · raw file

  1. class DYNAMIC_SHARED_OBJECT
  2. -- A dynamic shared object loaded with the support of the operative system,
  3. -- also known as .so libraries or as DLL.
  4. -- Insert DYNAMIC_LINKING_LOADER and use `new_dynamic_shared_object' or
  5. -- `main_program' to get an instance of this class.
  6. -- Currently available only on POSIX systems where it wraps dlopen
  7. inherit
  8. WRAPPER
  9. insert
  10. DL_FLAGS
  11. DLFCN_EXTERNALS
  12. create {DYNAMIC_LINKING_LOADER} from_external_pointer
  13. feature {ANY} -- Command
  14. set_flags (some_flags: INTEGER)
  15. -- Change the flags
  16. require are_valid_dlflags(some_flags)
  17. local h,ptr: POINTER
  18. do
  19. -- Using dlopen with rtld_noload to promote the flags on a library that
  20. -- is already loaded. For example, a library that was previously
  21. -- loaded with RTLD_LOCAL can be re-opened with RTLD_NOLOAD |
  22. -- RTLD_GLOBAL. This flag is not specified in POSIX.1-2001.
  23. if name/=Void then h:=name.to_external end
  24. ptr:=dlopen(h,some_flags)
  25. check
  26. handle=ptr
  27. end
  28. end
  29. feature {DYNAMIC_LINKING_LOADER, DL_LOADER}
  30. set_name (a_name: ABSTRACT_STRING)
  31. do
  32. name:=a_name
  33. end
  34. feature {ANY} -- Symbol query
  35. name: ABSTRACT_STRING
  36. -- The filename where Current have been loaded from. Void when Current refers to the main program
  37. attribute
  38. end
  39. symbol (a_symbol: ABSTRACT_STRING): POINTER
  40. -- The address where `a_symbol' - belonging to Current - is loaded into
  41. -- memory. If it is not found, either in Current or in its dependecies
  42. -- Result will be default_pointer. The search performed is breadth
  43. -- first through the dependency tree of these libraries. Since the
  44. -- value of the symbol could actually be default_pointer (defined as
  45. -- NULL in C) the correct way to test for an error is to assign
  46. -- `error' to a local string, invoke `symbol' and assign `error' again
  47. -- checking for the last value.
  48. -- foo (a_dll: DYNAMIC_SHARED_OBJECT) is
  49. -- require a_dll/=Void
  50. -- local precall_status, post_status: STRING; my_symbol: POINTER
  51. -- do
  52. -- precall_status := a_dll.error
  53. -- my_symbol := a_dll.symbol("foo")
  54. -- post_status := a_dll.error
  55. -- if post_status/=Void then -- everything ok
  56. -- else -- error resolving "foo"
  57. -- end
  58. -- Do not write "if a_dll.symbol("foo").is_not_null", defaull_pointer may be the actual value of "foo"
  59. -- Do not write "my_symbol:=a_dll.symbol("foo") if a_dll.error/=Void
  60. -- then print(a_dll.error)", because error is resetted every time it
  61. -- invoked; the print command will ALWAYS fails because its argument
  62. -- will be NULL.
  63. -- There are two special pseudo-handles, "RTLD_DEFAULT" and
  64. -- "RTLD_NEXT". The former will find the first occurrence of the
  65. -- desired symbol using the default library search order. The latter
  66. -- will find the next occurrence of a function in the search order
  67. -- after the current library. This allows one to provide a wrapper
  68. -- around a function in another shared library.
  69. do
  70. Result:=dlsym(handle,a_symbol.to_external)
  71. end
  72. feature {ANY} -- Error handling
  73. error: FIXED_STRING
  74. -- A human readable description of the most recent error that
  75. -- occurred during DYNAMIC_SHARED_OBJECT lifetime - creation, symbol
  76. -- query and disposing. Void when no error occurred. A new string is allocated at every query
  77. local ptr: POINTER
  78. do
  79. ptr :=dlerror
  80. if ptr.is_not_null then
  81. create Result.from_external_copy(ptr)
  82. end
  83. end
  84. feature {ANY} -- Disposing
  85. dispose
  86. -- Invokes dlclose; it decrements the reference count on the dynamic library handle handle. If the reference
  87. -- count drops to zero and no other loaded libraries use symbols in it, then the dynamic library is unloaded.
  88. local r: INTEGER
  89. do
  90. r:=dlclose(handle)
  91. -- TODO: handle dlclose results: 0 on success, and non-zero on error.
  92. end
  93. feature {} -- Unwrapped
  94. -- TODO: provide access to Glibc dladdr() and dlvsym() extensions functions
  95. end -- class DYNAMIC_SHARED_OBJECT
  96. -- Liberty Eiffel wrappers for GNU C library Copyright (C) 2013-2017: Paolo Redaelli, Free Software Foundation
  97. --
  98. -- The GNU C Library is free software; you can redistribute it and/or
  99. -- modify it under the terms of the GNU Lesser General Public
  100. -- License as published by the Free Software Foundation; either
  101. -- version 2.1 of the License, or (at your option) any later version.
  102. --
  103. -- The GNU C Library is distributed in the hope that it will be useful,
  104. -- but WITHOUT ANY WARRANTY; without even the implied warranty of
  105. -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  106. -- Lesser General Public License for more details.
  107. --
  108. -- You should have received a copy of the GNU Lesser General Public
  109. -- License along with the GNU C Library; if not, write to the Free
  110. -- Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  111. -- 02110-1301 USA