5 #if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
12 mutex_class
& global_mutex()
20 #if defined(_WIN32) || defined(_WIN64)
21 std::string callsign
= "dynamic link library";
22 std::string callsign_ext
= "dll";
23 #elif !defined(NO_DLFCN)
24 #if defined(__APPLE__)
25 std::string callsign
= "dynamic library";
26 std::string callsign_ext
= "bundle";
28 std::string callsign
= "shared object";
29 std::string callsign_ext
= "so";
32 std::string callsign
= "";
36 library::internal::internal(const std::string
& filename
) throw(std::bad_alloc
, std::runtime_error
)
39 #if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
41 getcwd(buffer
, 16383);
42 std::string _filename
= filename
;
43 if(filename
.find_first_of("/") >= filename
.length())
44 _filename
= buffer
+ std::string("/") + filename
;
45 handle
= dlopen(_filename
.c_str(), RTLD_LOCAL
| RTLD_NOW
);
47 throw std::runtime_error(dlerror());
48 #elif defined(_WIN32) || defined(_WIN64)
50 GetCurrentDirectory(16383, buffer
);
51 std::string _filename
= filename
;
52 if(filename
.find_first_of("/\\") >= filename
.length())
53 _filename
= buffer
+ std::string("/") + filename
;
54 handle
= LoadLibraryA(_filename
.c_str());
56 int errcode
= GetLastError();
57 char errorbuffer
[1024];
58 if(FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS
| FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, errcode
, 0,
59 errorbuffer
, sizeof(errorbuffer
), NULL
))
60 throw std::runtime_error(errorbuffer
);
62 std::ostringstream str
;
63 str
<< "Unknown system error (code " << errcode
<< ")";
64 throw std::runtime_error(str
.str());
68 throw std::runtime_error("Loading libraries is not supported");
72 library::internal::~internal() throw()
74 #if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
76 #elif defined(_WIN32) || defined(_WIN64)
81 void* library::internal::operator[](const std::string
& symbol
) const throw(std::bad_alloc
, std::runtime_error
)
83 #if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
85 void* s
= dlsym(handle
, symbol
.c_str());
90 throw std::runtime_error(e
);
91 return NULL
; //Yes, real NULL symbol.
92 #elif defined(_WIN32) || defined(_WIN64)
93 void* s
= (void*)GetProcAddress(handle
, symbol
.c_str());
96 int errcode
= GetLastError();
97 char errorbuffer
[1024];
98 if(FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS
| FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, errcode
, 0,
99 errorbuffer
, sizeof(errorbuffer
), NULL
))
100 throw std::runtime_error(errorbuffer
);
102 std::ostringstream str
;
103 str
<< "Unknown system error (code " << errcode
<< ")";
104 throw std::runtime_error(str
.str());
107 throw std::runtime_error("Library loading not supported");
111 const std::string
& library::name() throw()
116 const std::string
& library::extension() throw()
123 std::list
<loadlib::module
*>& module_queue()
125 static std::list
<module
*> x
;
130 module::module(std::initializer_list
<symbol
> _symbols
, std::function
<void(const module
&)> init_fn
)
133 for(auto i
: _symbols
)
134 symbols
[i
.name
] = i
.address
;
137 umutex_class
h(global_mutex());
138 module_queue().push_back(this);
142 module::module(library _lib
)
150 umutex_class
h(global_mutex());
151 for(auto i
= module_queue().begin(); i
!= module_queue().end(); i
++) {
153 module_queue().erase(i
);
159 module::module(const module
& mod
)
161 dynamic
= mod
.dynamic
;
163 symbols
= mod
.symbols
;
166 umutex_class
h(global_mutex());
167 module_queue().push_back(this);
171 void* module::operator[](const std::string
& symbol
) const throw(std::bad_alloc
, std::runtime_error
)
175 else if(symbols
.count(symbol
))
176 return symbols
.find(symbol
)->second
;
178 throw std::runtime_error("Symbol '" + symbol
+ "' not found");
181 void module::run_initializers()
183 for(auto i
: module_queue())
186 i
->init
= std::function
<void(const module
&)>();
188 module_queue().clear();