YARP
Yet Another Robot Platform
SharedLibrary.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
7 
8 #include <yarp/conf/system.h>
9 
10 #include <yarp/os/Log.h>
11 
12 #include <string>
13 
14 #ifdef YARP_HAS_ACE
15 # include <ace/ACE.h>
16 # include <ace/DLL.h>
17 // In one the ACE headers there is a definition of "main" for WIN32
18 # ifdef main
19 # undef main
20 # endif
21 #else
23 #endif
24 
25 
28 
29 
31 {
32 public:
33  SharedLibraryImpl() = default;
34 
35  inline char* getError()
36  {
37 #ifdef YARP_HAS_ACE
38  if (dll != nullptr) {
39  return dll->error();
40  }
41  return const_cast<char*>("Unknown error");
42 #else
43  return yarp::os::impl::dlerror();
44 #endif
45  }
46 
47 #ifdef YARP_HAS_ACE
48  ACE_DLL* dll{nullptr};
49 #else
50  void* dll;
51 #endif
52  std::string error;
53 };
54 
55 
56 SharedLibrary::SharedLibrary() :
58 {
59  yAssert(implementation != nullptr);
60 }
61 
62 SharedLibrary::SharedLibrary(const char* filename) :
64 {
65  yAssert(implementation != nullptr);
66  open(filename);
67 }
68 
70 {
71  yAssert(implementation != nullptr);
72  close();
73  delete implementation;
74 }
75 
76 bool SharedLibrary::open(const char* filename)
77 {
78  close();
79 #ifdef YARP_HAS_ACE
80  implementation->dll = new ACE_DLL();
81  yAssert(implementation->dll);
82  int result = implementation->dll->open(filename);
83  if (result != 0) {
84  // Save error since close might overwrite it
85  std::string error(implementation->getError());
86  close();
87  implementation->error = error;
88  return false;
89  }
90  return true;
91 #else
92  implementation->dll = yarp::os::impl::dlopen(filename, RTLD_LAZY);
93  if (!implementation->dll) {
94  implementation->error = implementation->getError();
95  return false;
96  }
97  return true;
98 #endif
99 }
100 
102 {
103  int result = 0;
104  if (implementation->dll != nullptr) {
105 #ifdef YARP_HAS_ACE
106  result = implementation->dll->close();
107  delete implementation->dll;
108 #else
109  result = yarp::os::impl::dlclose(implementation->dll);
110 #endif
111  implementation->dll = nullptr;
112  }
113 
114  if (result != 0) {
115  implementation->error = implementation->getError();
116  }
117 
118  return (result == 0);
119 }
120 
121 std::string SharedLibrary::error()
122 {
123  return SharedLibrary::implementation->error;
124 }
125 
126 void* SharedLibrary::getSymbol(const char* symbolName)
127 {
128  if (implementation->dll == nullptr) {
129  implementation->error = "Library is not open";
130  return nullptr;
131  }
132 
133 #ifdef YARP_HAS_ACE
134  void* result = implementation->dll->symbol(symbolName);
135 #else
136  void* result = yarp::os::impl::dlsym(implementation->dll, symbolName);
137 #endif
138  if (result == nullptr) {
139  implementation->error = implementation->getError();
140  }
141 
142  return result;
143 }
144 
146 {
147  return implementation->dll != nullptr;
148 }
#define yAssert(x)
Definition: Log.h:294
RandScalar * implementation(void *t)
Definition: RandnScalar.cpp:17
Low-level wrapper for loading shared libraries (DLLs) and accessing symbols within it.
Definition: SharedLibrary.h:31
bool open(const char *filename)
Load the named shared library / DLL.
std::string error()
Returns a human-readable string describing the most recent error that occurred from a call to one of ...
virtual ~SharedLibrary()
Destructor.
bool isValid() const
Check if the shared library is valid.
SharedLibrary()
Initialize, without opening a shared library yet.
bool close()
Shared library no longer needed, unload if not in use elsewhere.
void * getSymbol(const char *symbolName)
Look up a symbol in the shared library.