
inalhdl.spinalhdl-sim_2.13.1.11.0.source-code.xsi_shared_lib.h Maven / Gradle / Ivy
/*
* xsi_shared_library.h
* Copyright (c) 2012, Xilinx, Inc. All Rights Reserved.
* Class for loading shared libraries generated by xelab
*/
#ifndef _XSI_SHARED_LIB_H
#define _XSI_SHARED_LIB_H
#if defined(_WIN32)
# include
#else
# include
#endif
#include
#include
namespace Xsi {
class SharedLibrary {
public:
#if defined(_WIN32)
typedef HINSTANCE handle_type;
#else
typedef void * handle_type;
#endif
typedef void * symbol_type;
SharedLibrary() : _lib(0), _retain(false) { }
~SharedLibrary() { unload(); }
operator bool() const { return (_lib != 0); }
bool loaded() const { return (_lib != 0); }
handle_type handle() const { return _lib; }
const std::string& path() const { return _path; }
const std::string& error() const { return _err; }
bool load(const std::string& path)
{
unload();
// reset the retain flag
_retain = false;
if (path.empty()) {
_err = "Failed to load shared library. "
"Path of the shared library is not specified.";
return false;
}
std::string msg;
bool ok = load_impl(path, msg);
if (ok) {
_path = path;
_err.clear();
}
else {
_err = "Failed to load shared library \"" + path +
"\". " + msg;
}
return ok;
}
bool load_impl(const std::string& path, std::string& errmsg)
{
bool ok = true;
#if defined(_WIN32)
SetLastError(0);
_lib = LoadLibrary(path.c_str());
if (_lib == 0) {
translate_error_message(GetLastError(), errmsg);
ok = false;
}
#else
_lib = dlopen(path.c_str(), RTLD_LAZY | RTLD_GLOBAL);
char *err = dlerror();
if (err != NULL) {
errmsg = err;
ok = false;
}
#endif
return ok;
}
void unload()
{
if (_lib) {
if (!_retain) {
#if defined(_WIN32)
FreeLibrary(_lib);
#else
dlclose(_lib);
#endif
}
_lib = 0;
}
_err.clear();
}
void retain()
{
_retain = true;
}
bool getsymbol(const std::string& name, symbol_type& sym)
{
std::string msg;
bool ok = true;
if (_lib == 0) {
msg = "The shared library is not loaded.";
ok = false;
}
else {
#if defined(_WIN32)
sym = (void*) GetProcAddress(_lib, name.c_str());
if (sym == NULL) {
translate_error_message(GetLastError(), msg);
ok = false;
}
#else
dlerror(); // clear error
sym = (void *) dlsym(_lib, name.c_str());
char *err = dlerror();
if (err != NULL) {
msg = err;
ok = false;
}
#endif
}
if (ok) {
_err.clear();
}
else {
_err = "Failed to obtain symbol \"" + name +
"\" from shared library. " + msg;
}
return ok;
}
symbol_type getfunction(const std::string& name)
{
symbol_type sym = NULL;
return getsymbol(name, sym) ? sym : NULL;
}
private:
// shared library is non-copyable
SharedLibrary(const SharedLibrary&);
const SharedLibrary& operator=(const SharedLibrary&);
#if defined(_WIN32)
static void translate_error_message(DWORD errid, std::string& msg)
{
LPVOID bufptr;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
errid,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &bufptr,
0,
NULL);
msg.clear();
if (bufptr) {
msg = reinterpret_cast(bufptr);
}
LocalFree(bufptr);
}
static const std::string& library_suffix()
{
static const std::string s = ".dll";
return s;
}
#else
static const std::string& library_suffix()
{
static const std::string s = ".so";
return s;
}
#endif
handle_type _lib;
std::string _path;
std::string _err;
bool _retain;
};
} // namespace Xsi
#endif // _XSI_SHARED_LIB_H
© 2015 - 2025 Weber Informatics LLC | Privacy Policy