2013-08-29 11:45:22 +09:00
|
|
|
/*
|
|
|
|
Copyright (c) 2013 yvt
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-29 11:45:22 +09:00
|
|
|
This file is part of OpenSpades.
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-29 11:45:22 +09:00
|
|
|
OpenSpades is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-29 11:45:22 +09:00
|
|
|
OpenSpades is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-29 11:45:22 +09:00
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-29 11:45:22 +09:00
|
|
|
*/
|
2013-08-18 16:18:06 +09:00
|
|
|
|
2014-04-01 15:52:40 +09:00
|
|
|
#include <Imports/SDL.h>
|
|
|
|
|
2013-08-18 16:18:06 +09:00
|
|
|
#ifdef WIN32
|
|
|
|
|
|
|
|
#include <windows.h>
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-18 16:18:06 +09:00
|
|
|
#include "Debug.h"
|
2016-12-03 18:23:47 +09:00
|
|
|
#include "DynamicLibrary.h"
|
|
|
|
#include "Exception.h"
|
2013-08-18 16:18:06 +09:00
|
|
|
|
|
|
|
namespace spades {
|
2013-12-24 00:31:51 +01:00
|
|
|
|
2016-12-03 18:23:47 +09:00
|
|
|
static std::string errToMsg(DWORD err) {
|
2013-12-24 00:31:51 +01:00
|
|
|
LPSTR msgBuf = NULL;
|
2016-12-03 18:23:47 +09:00
|
|
|
DWORD dwFmt = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
|
|
|
FORMAT_MESSAGE_IGNORE_INSERTS;
|
|
|
|
size_t size = FormatMessageA(dwFmt, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
|
|
(LPSTR)&msgBuf, 0, NULL);
|
2013-12-24 00:31:51 +01:00
|
|
|
std::string message(msgBuf, size);
|
|
|
|
LocalFree(msgBuf);
|
|
|
|
return message;
|
|
|
|
}
|
|
|
|
|
2016-12-03 18:23:47 +09:00
|
|
|
DynamicLibrary::DynamicLibrary(const char *fn) {
|
2013-08-18 16:18:06 +09:00
|
|
|
SPADES_MARK_FUNCTION();
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-18 16:18:06 +09:00
|
|
|
name = fn;
|
|
|
|
handle = (void *)LoadLibrary(fn);
|
2016-12-03 18:23:47 +09:00
|
|
|
if (handle == NULL) {
|
2013-08-18 16:18:06 +09:00
|
|
|
DWORD err = GetLastError();
|
2016-12-03 18:23:47 +09:00
|
|
|
std::string msg = errToMsg(err);
|
2013-12-24 00:31:51 +01:00
|
|
|
SPRaise("Failed to dlload '%s': 0x%08x (%s)", fn, (int)err, msg.c_str());
|
2013-08-18 16:18:06 +09:00
|
|
|
}
|
|
|
|
}
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-18 16:18:06 +09:00
|
|
|
DynamicLibrary::~DynamicLibrary() {
|
|
|
|
SPADES_MARK_FUNCTION();
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-18 16:18:06 +09:00
|
|
|
FreeLibrary((HINSTANCE)handle);
|
|
|
|
}
|
2016-12-03 18:23:47 +09:00
|
|
|
|
|
|
|
void *DynamicLibrary::GetSymbolOrNull(const char *name) {
|
2013-08-18 16:18:06 +09:00
|
|
|
SPADES_MARK_FUNCTION();
|
2016-12-03 18:23:47 +09:00
|
|
|
|
|
|
|
void *addr = (void *)GetProcAddress((HINSTANCE)handle, name);
|
2013-08-18 16:18:06 +09:00
|
|
|
return addr;
|
|
|
|
}
|
2016-12-03 18:23:47 +09:00
|
|
|
|
|
|
|
void *DynamicLibrary::GetSymbol(const char *sname) {
|
2013-08-18 16:18:06 +09:00
|
|
|
SPADES_MARK_FUNCTION();
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-18 16:18:06 +09:00
|
|
|
void *v = GetSymbolOrNull(sname);
|
2016-12-03 18:23:47 +09:00
|
|
|
if (v == NULL) {
|
2013-08-18 16:18:06 +09:00
|
|
|
DWORD err = GetLastError();
|
2016-12-03 18:23:47 +09:00
|
|
|
std::string msg = errToMsg(err);
|
|
|
|
SPRaise("Failed to find symbol '%s' in %s: 0x%08x (%s)", sname, name.c_str(), err,
|
|
|
|
msg.c_str());
|
2013-08-18 16:18:06 +09:00
|
|
|
}
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
2016-12-03 18:23:47 +09:00
|
|
|
#include "Debug.h"
|
2013-08-18 16:18:06 +09:00
|
|
|
#include "DynamicLibrary.h"
|
|
|
|
#include "Exception.h"
|
|
|
|
#include <dlfcn.h>
|
|
|
|
|
|
|
|
namespace spades {
|
2016-12-03 18:23:47 +09:00
|
|
|
DynamicLibrary::DynamicLibrary(const char *fn) {
|
2013-08-18 16:18:06 +09:00
|
|
|
SPADES_MARK_FUNCTION();
|
2016-12-03 18:23:47 +09:00
|
|
|
|
|
|
|
if (fn == nullptr) {
|
2014-04-01 15:52:40 +09:00
|
|
|
SPInvalidArgument("fn");
|
|
|
|
}
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-18 16:18:06 +09:00
|
|
|
name = fn;
|
|
|
|
handle = dlopen(fn, RTLD_LAZY);
|
2017-10-14 15:56:36 +01:00
|
|
|
#ifndef __OpenBSD__
|
2016-12-03 18:23:47 +09:00
|
|
|
if (handle == nullptr && strchr(fn, '/') == nullptr && strchr(fn, '\\') == nullptr) {
|
2014-04-01 15:52:40 +09:00
|
|
|
char *baseDir = SDL_GetBasePath();
|
|
|
|
std::string newPath = baseDir;
|
|
|
|
newPath += "/";
|
|
|
|
newPath += fn;
|
|
|
|
handle = dlopen(newPath.c_str(), RTLD_LAZY);
|
|
|
|
}
|
2017-10-14 15:56:36 +01:00
|
|
|
#endif
|
2016-12-03 18:23:47 +09:00
|
|
|
if (handle == nullptr) {
|
2013-08-18 16:18:06 +09:00
|
|
|
std::string err = dlerror();
|
|
|
|
SPRaise("Failed to dlload '%s': %s", fn, err.c_str());
|
|
|
|
}
|
|
|
|
}
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-18 16:18:06 +09:00
|
|
|
DynamicLibrary::~DynamicLibrary() {
|
|
|
|
SPADES_MARK_FUNCTION();
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-18 16:18:06 +09:00
|
|
|
dlclose(handle);
|
|
|
|
}
|
2016-12-03 18:23:47 +09:00
|
|
|
|
|
|
|
void *DynamicLibrary::GetSymbolOrNull(const char *name) {
|
2013-08-18 16:18:06 +09:00
|
|
|
SPADES_MARK_FUNCTION();
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-18 16:18:06 +09:00
|
|
|
void *addr = dlsym(handle, name);
|
|
|
|
return addr;
|
|
|
|
}
|
2016-12-03 18:23:47 +09:00
|
|
|
|
|
|
|
void *DynamicLibrary::GetSymbol(const char *sname) {
|
2013-08-18 16:18:06 +09:00
|
|
|
SPADES_MARK_FUNCTION();
|
2016-12-03 18:23:47 +09:00
|
|
|
|
2013-08-18 16:18:06 +09:00
|
|
|
void *v = GetSymbolOrNull(sname);
|
2016-12-03 18:23:47 +09:00
|
|
|
if (v == NULL) {
|
2013-08-18 16:18:06 +09:00
|
|
|
std::string err = dlerror();
|
2016-12-03 18:23:47 +09:00
|
|
|
SPRaise("Failed to find symbol '%s' in %s: %s", sname, name.c_str(), err.c_str());
|
2013-08-18 16:18:06 +09:00
|
|
|
}
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|