Allow specifying ROM type in file load dialog
[lsnes.git] / src / library / loadlib.cpp
blobda6adf13a4d520e22e6bc384c7895e2fe1095932
1 #include "loadlib.hpp"
2 #include <sstream>
4 #if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
5 #include <dlfcn.h>
6 #include <unistd.h>
7 #endif
9 namespace
11 #if defined(_WIN32) || defined(_WIN64)
12 std::string callsign = "dynamic link library";
13 std::string callsign_ext = "dll";
14 #elif !defined(NO_DLFCN)
15 #if defined(__APPLE__)
16 std::string callsign = "dynamic library";
17 std::string callsign_ext = "bundle";
18 #else
19 std::string callsign = "shared object";
20 std::string callsign_ext = "so";
21 #endif
22 #else
23 std::string callsign = "";
24 #endif
27 loaded_library::loaded_library(const std::string& filename) throw(std::bad_alloc, std::runtime_error)
29 #if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
30 char buffer[16384];
31 getcwd(buffer, 16383);
32 std::string _filename = filename;
33 if(filename.find_first_of("/") >= filename.length())
34 _filename = buffer + std::string("/") + filename;
35 handle = dlopen(_filename.c_str(), RTLD_LOCAL | RTLD_NOW);
36 if(!handle)
37 throw std::runtime_error(dlerror());
38 #elif defined(_WIN32) || defined(_WIN64)
39 char buffer[16384];
40 GetCurrentDirectory(16383, buffer);
41 std::string _filename = filename;
42 if(filename.find_first_of("/\\") >= filename.length())
43 _filename = buffer + std::string("/") + filename;
44 handle = LoadLibraryA(_filename.c_str());
45 if(!handle) {
46 int errcode = GetLastError();
47 char errorbuffer[1024];
48 if(FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, NULL, errcode, 0,
49 errorbuffer, sizeof(errorbuffer), NULL))
50 throw std::runtime_error(errorbuffer);
51 else {
52 std::ostringstream str;
53 str << "Unknown system error (code " << errcode << ")";
54 throw std::runtime_error(str.str());
57 #else
58 throw std::runtime_error("Loading libraries is not supported");
59 #endif
62 loaded_library::~loaded_library() throw()
64 #if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
65 dlclose(handle);
66 #elif defined(_WIN32) || defined(_WIN64)
67 FreeLibrary(handle);
68 #endif
71 void* loaded_library::operator[](const std::string& symbol) throw(std::bad_alloc, std::runtime_error)
73 #if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
74 dlerror();
75 void* s = dlsym(handle, symbol.c_str());
76 if(s)
77 return s;
78 char* e = dlerror();
79 if(e)
80 throw std::runtime_error(e);
81 return NULL; //Yes, real NULL symbol.
82 #elif defined(_WIN32) || defined(_WIN64)
83 void* s = (void*)GetProcAddress(handle, symbol.c_str());
84 if(s)
85 return s;
86 int errcode = GetLastError();
87 char errorbuffer[1024];
88 if(FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, NULL, errcode, 0,
89 errorbuffer, sizeof(errorbuffer), NULL))
90 throw std::runtime_error(errorbuffer);
91 else {
92 std::ostringstream str;
93 str << "Unknown system error (code " << errcode << ")";
94 throw std::runtime_error(str.str());
96 #else
97 throw std::runtime_error("Library loading not supported");
98 #endif
101 const std::string& loaded_library::call_library() throw()
103 return callsign;
106 const std::string& loaded_library::call_library_ext() throw()
108 return callsign_ext;