6 #if defined(_WIN32) || defined(_WIN64)
10 #if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
17 threads::lock
& global_mutex()
19 static threads::lock m
;
25 thread_local library
* currently_loading
;
26 #if defined(_WIN32) || defined(_WIN64)
27 std::string callsign
= "dynamic link library";
28 std::string callsign_ext
= "dll";
29 #elif !defined(NO_DLFCN)
30 #if defined(__APPLE__)
31 std::string callsign
= "dynamic library";
32 std::string callsign_ext
= "bundle";
34 std::string callsign
= "shared object";
35 std::string callsign_ext
= "so";
38 std::string callsign
= "";
39 std::string callsign_ext
= "";
43 library::internal::internal(const std::string
& filename
) throw(std::bad_alloc
, std::runtime_error
)
47 #if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
49 getcwd(buffer
, 16383);
50 std::string _filename
= filename
;
51 if(filename
.find_first_of("/") >= filename
.length())
52 _filename
= buffer
+ std::string("/") + filename
;
53 handle
= dlopen(_filename
.c_str(), RTLD_LOCAL
| RTLD_NOW
);
55 throw std::runtime_error(dlerror());
56 #elif defined(_WIN32) || defined(_WIN64)
58 GetCurrentDirectory(16383, buffer
);
59 std::string _filename
= filename
;
60 if(filename
.find_first_of("/\\") >= filename
.length())
61 _filename
= buffer
+ std::string("/") + filename
;
62 handle
= LoadLibraryA(_filename
.c_str());
64 int errcode
= GetLastError();
65 char errorbuffer
[1024];
66 if(FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS
| FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, errcode
, 0,
67 errorbuffer
, sizeof(errorbuffer
), NULL
))
68 throw std::runtime_error(errorbuffer
);
70 std::ostringstream str
;
71 str
<< "Unknown system error (code " << errcode
<< ")";
72 throw std::runtime_error(str
.str());
76 throw std::runtime_error("Loading libraries is not supported");
80 library::internal::~internal() throw()
82 #if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
84 #elif defined(_WIN32) || defined(_WIN64)
85 FreeLibrary((HMODULE
)handle
);
89 void* library::internal::operator[](const std::string
& symbol
) const throw(std::bad_alloc
, std::runtime_error
)
91 #if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
93 void* s
= dlsym(handle
, symbol
.c_str());
98 throw std::runtime_error(e
);
99 return NULL
; //Yes, real NULL symbol.
100 #elif defined(_WIN32) || defined(_WIN64)
101 void* s
= (void*)GetProcAddress((HMODULE
)handle
, symbol
.c_str());
104 int errcode
= GetLastError();
105 char errorbuffer
[1024];
106 if(FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS
| FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, errcode
, 0,
107 errorbuffer
, sizeof(errorbuffer
), NULL
))
108 throw std::runtime_error(errorbuffer
);
110 std::ostringstream str
;
111 str
<< "Unknown system error (code " << errcode
<< ")";
112 throw std::runtime_error(str
.str());
115 throw std::runtime_error("Library loading not supported");
119 const std::string
& library::name() throw()
124 const std::string
& library::extension() throw()
129 library
* library::loading() throw() { return currently_loading
; }
130 void library::set_loading(library
* lib
) throw(std::bad_alloc
) { currently_loading
= lib
; }
134 std::list
<loadlib::module
*>& module_queue()
136 static std::list
<module
*> x
;
141 module::module(std::initializer_list
<symbol
> _symbols
, std::function
<void(const module
&)> init_fn
)
144 for(auto i
: _symbols
)
145 symbols
[i
.name
] = i
.address
;
148 threads::alock
h(global_mutex());
149 module_queue().push_back(this);
151 libname
= "<anonymous module inside executable>";
154 module::module(library _lib
)
158 libname
= _lib
.get_libname();
163 threads::alock
h(global_mutex());
164 for(auto i
= module_queue().begin(); i
!= module_queue().end(); i
++) {
166 module_queue().erase(i
);
172 module::module(const module
& mod
)
174 dynamic
= mod
.dynamic
;
176 symbols
= mod
.symbols
;
178 libname
= mod
.libname
;
180 threads::alock
h(global_mutex());
181 module_queue().push_back(this);
185 void* module::operator[](const std::string
& symbol
) const throw(std::bad_alloc
, std::runtime_error
)
189 else if(symbols
.count(symbol
))
190 return symbols
.find(symbol
)->second
;
192 throw std::runtime_error("Symbol '" + symbol
+ "' not found");
195 void module::run_initializers()
197 for(auto i
: module_queue())
200 i
->init
= std::function
<void(const module
&)>();
202 module_queue().clear();