Refactor and extend library loading
This commit is contained in:
parent
68ccf06684
commit
92c6d5f5af
5 changed files with 109 additions and 76 deletions
|
@ -1,10 +0,0 @@
|
|||
#ifndef _loadlib__hpp__included__
|
||||
#define _loadlib__hpp__included__
|
||||
|
||||
#include <string>
|
||||
|
||||
void load_library(const std::string& filename);
|
||||
extern const bool load_library_supported;
|
||||
extern const char* library_is_called;
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
#include "core/loadlib.hpp"
|
||||
#include "library/loadlib.hpp"
|
||||
#include "core/command.hpp"
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
|
@ -8,7 +8,7 @@ namespace {
|
|||
"Syntax: load-library <file>\nLoad library <file>\n",
|
||||
[](arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
try {
|
||||
load_library(args);
|
||||
new loaded_library(args);
|
||||
} catch(std::exception& e) {
|
||||
std::ostringstream x;
|
||||
x << "Can't load '" << std::string(args) << "': " << e.what();
|
||||
|
@ -16,60 +16,3 @@ namespace {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
#if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
void load_library(const std::string& filename)
|
||||
{
|
||||
char buffer[16384];
|
||||
getcwd(buffer, 16383);
|
||||
std::string _filename = filename;
|
||||
if(filename.find_first_of("/") >= filename.length())
|
||||
_filename = buffer + std::string("/") + filename;
|
||||
void* h = dlopen(_filename.c_str(), RTLD_LOCAL | RTLD_NOW);
|
||||
if(!h)
|
||||
throw std::runtime_error(dlerror());
|
||||
}
|
||||
extern const bool load_library_supported = true;
|
||||
#ifdef __APPLE__
|
||||
const char* library_is_called = "Dynamic Library";
|
||||
#else
|
||||
const char* library_is_called = "Shared Object";
|
||||
#endif
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
void load_library(const std::string& filename)
|
||||
{
|
||||
char buffer[16384];
|
||||
GetCurrentDirectory(16383, buffer);
|
||||
std::string _filename = filename;
|
||||
if(filename.find_first_of("/\\") >= filename.length())
|
||||
_filename = buffer + std::string("/") + filename;
|
||||
HMODULE h = LoadLibraryA(_filename.c_str());
|
||||
if(!h) {
|
||||
int errcode = GetLastError();
|
||||
char errorbuffer[1024];
|
||||
if(FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, NULL, errcode, 0,
|
||||
errorbuffer, sizeof(errorbuffer), NULL))
|
||||
throw std::runtime_error(errorbuffer);
|
||||
else {
|
||||
std::ostringstream str;
|
||||
str << "Unknown system error (code " << errcode << ")";
|
||||
throw std::runtime_error(str.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
extern const bool load_library_supported = true;
|
||||
const char* library_is_called = "Dynamic Link Library";
|
||||
#else
|
||||
void load_library(const std::string& filename)
|
||||
{
|
||||
throw std::runtime_error("Library loader not supported on this platform");
|
||||
}
|
||||
extern const bool load_library_supported = false;
|
||||
const char* library_is_called = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
100
src/library/loadlib.cpp
Normal file
100
src/library/loadlib.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
#include "library/loadlib.hpp"
|
||||
|
||||
#if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
std::string callsign = "dynamic link library";
|
||||
#elif !defined(NO_DLFCN)
|
||||
#if defined(__APPLE__)
|
||||
std::string callsign = "dynamic library";
|
||||
#else
|
||||
std::string callsign = "shared object";
|
||||
#endif
|
||||
#else
|
||||
std::string callsign = "";
|
||||
#endif
|
||||
}
|
||||
|
||||
loaded_library::loaded_library(const std::string& filename) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
#if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
|
||||
char buffer[16384];
|
||||
getcwd(buffer, 16383);
|
||||
std::string _filename = filename;
|
||||
if(filename.find_first_of("/") >= filename.length())
|
||||
_filename = buffer + std::string("/") + filename;
|
||||
handle = dlopen(_filename.c_str(), RTLD_LOCAL | RTLD_NOW);
|
||||
if(!handle)
|
||||
throw std::runtime_error(dlerror());
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
char buffer[16384];
|
||||
GetCurrentDirectory(16383, buffer);
|
||||
std::string _filename = filename;
|
||||
if(filename.find_first_of("/\\") >= filename.length())
|
||||
_filename = buffer + std::string("/") + filename;
|
||||
handle = LoadLibraryA(_filename.c_str());
|
||||
if(!handle) {
|
||||
int errcode = GetLastError();
|
||||
char errorbuffer[1024];
|
||||
if(FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, NULL, errcode, 0,
|
||||
errorbuffer, sizeof(errorbuffer), NULL))
|
||||
throw std::runtime_error(errorbuffer);
|
||||
else {
|
||||
std::ostringstream str;
|
||||
str << "Unknown system error (code " << errcode << ")";
|
||||
throw std::runtime_error(str.str());
|
||||
}
|
||||
}
|
||||
#else
|
||||
throw std::runtime_error("Loading libraries is not supported");
|
||||
#endif
|
||||
}
|
||||
|
||||
loaded_library::~loaded_library() throw()
|
||||
{
|
||||
#if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
|
||||
dlclose(handle);
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
FreeLibrary(handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
void* loaded_library::operator[](const std::string& symbol) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
#if !defined(NO_DLFCN) && !defined(_WIN32) && !defined(_WIN64)
|
||||
dlerror();
|
||||
void* s = dlsym(handle, symbol.c_str());
|
||||
if(s)
|
||||
return s;
|
||||
char* e = dlerror();
|
||||
if(e)
|
||||
throw std::runtime_error(e);
|
||||
return NULL; //Yes, real NULL symbol.
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
void* s = GetProcAddress(handle, symbol.c_str());
|
||||
if(s)
|
||||
return s;
|
||||
int errcode = GetLastError();
|
||||
char errorbuffer[1024];
|
||||
if(FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, NULL, errcode, 0,
|
||||
errorbuffer, sizeof(errorbuffer), NULL))
|
||||
throw std::runtime_error(errorbuffer);
|
||||
else {
|
||||
std::ostringstream str;
|
||||
str << "Unknown system error (code " << errcode << ")";
|
||||
throw std::runtime_error(str.str());
|
||||
}
|
||||
#else
|
||||
throw std::runtime_error("Library loading not supported");
|
||||
#endif
|
||||
}
|
||||
|
||||
const std::string& loaded_library::call_library() throw()
|
||||
{
|
||||
return callsign;
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
#include "core/dispatch.hpp"
|
||||
#include "core/framebuffer.hpp"
|
||||
#include "core/framerate.hpp"
|
||||
#include "core/loadlib.hpp"
|
||||
#include "library/loadlib.hpp"
|
||||
#include "lua/lua.hpp"
|
||||
#include "core/mainloop.hpp"
|
||||
#include "core/memorywatch.hpp"
|
||||
|
@ -772,9 +772,9 @@ wxwin_mainwindow::wxwin_mainwindow()
|
|||
menu_entry(wxID_LOAD_STATE_RW, wxT("State (read-write)..."));
|
||||
menu_entry(wxID_LOAD_STATE_P, wxT("State (preserve input)..."));
|
||||
menu_entry(wxID_LOAD_MOVIE, wxT("Movie..."));
|
||||
if(load_library_supported) {
|
||||
if(loaded_library::call_library() != "") {
|
||||
menu_separator();
|
||||
menu_entry(wxID_LOAD_LIBRARY, towxstring(std::string("Load ") + library_is_called));
|
||||
menu_entry(wxID_LOAD_LIBRARY, towxstring(std::string("Load ") + loaded_library::call_library()));
|
||||
}
|
||||
menu_separator();
|
||||
menu_entry(wxID_RELOAD_ROM_IMAGE, wxT("Reload ROM"));
|
||||
|
@ -1213,8 +1213,8 @@ void wxwin_mainwindow::handle_menu_click_cancelable(wxCommandEvent& e)
|
|||
set_speed(-1);
|
||||
break;
|
||||
case wxID_LOAD_LIBRARY: {
|
||||
std::string name = std::string("load ") + library_is_called;
|
||||
load_library(pick_file(this, name, ".", false));
|
||||
std::string name = std::string("load ") + loaded_library::call_library();
|
||||
new loaded_library(pick_file(this, name, ".", false));
|
||||
break;
|
||||
}
|
||||
case wxID_SETTINGS:
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "core/dispatch.hpp"
|
||||
#include "core/framerate.hpp"
|
||||
#include "core/keymapper.hpp"
|
||||
#include "core/loadlib.hpp"
|
||||
#include "library/loadlib.hpp"
|
||||
#include "lua/lua.hpp"
|
||||
#include "core/mainloop.hpp"
|
||||
#include "core/misc.hpp"
|
||||
|
@ -163,7 +163,7 @@ namespace
|
|||
}
|
||||
} else if(a.length() >= 12 && a.substr(0, 15) == "--load-library=")
|
||||
try {
|
||||
load_library(a.substr(15));
|
||||
new loaded_library(a.substr(15));
|
||||
} catch(std::runtime_error& e) {
|
||||
std::cerr << "Can't load '" << a.substr(15) << "': " << e.what() << std::endl;
|
||||
exit(1);
|
||||
|
|
Loading…
Add table
Reference in a new issue