SFML/DSFML/import/dsfml/system/dllloader.d

206 lines
3.9 KiB
D

/*
* DSFML - SFML Library wrapper for the D programming language.
* Copyright (C) 2008 Julien Dagorn (sirjulio13@gmail.com)
* Copyright (C) 2010 Andreas Hollandt
*
* This software is provided 'as-is', without any express or
* implied warranty. In no event will the authors be held
* liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute
* it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented;
* you must not claim that you wrote the original software.
* If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but
* is not required.
*
* 2. Altered source versions must be plainly marked as such,
* and must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any
* source distribution.
*/
module dsfml.system.dllloader;
import dsfml.system.stringutil;
version (Tango)
{
import tango.io.Console;
import tango.sys.SharedLib;
}
else
{
import std.stdio;
version (Windows)
{
import std.c.windows.windows;
import std.windows.syserror; // for error strings
alias HMODULE MODULEHANDLE;
}
version (linux)
{
import std.c.linux.linux;
alias void* MODULEHANDLE;
const int RTLD_NOW = 0x00002;
const int RTLD_GLOBAL = 0x00100;
}
}
static this()
{
version (Tango)
{
SharedLib.throwExceptions = false;
}
}
static ~this()
{
// DllLoader.closeAll();
}
private void report(string msg, string lib, string symb)
{
string str = "Loading error. Reason : " ~ msg ~ " (library : " ~ lib ~ ", symbol : " ~ symb ~ ")";
version (Tango)
{
Cerr(str).newline;
}
else
{
stderr.writeln(str);
}
}
/**
* Simple Dll loader.
*/
class DllLoader
{
static DllLoader load(string library)
{
version (Windows)
{
string libraryName = library ~ ".dll";
}
version (linux)
{
string libraryName = "lib" ~ library ~ ".so";
}
if (libraryName in alreadyLoaded)
{
return alreadyLoaded[libraryName];
}
else
{
DllLoader temp = new DllLoader(libraryName);
alreadyLoaded[libraryName] = temp;
return temp;
}
}
void* getSymbol(string symbolName)
{
void* symb;
version (Tango)
{
symb = m_lib.getSymbol(toStringz(symbolName));
}
else
{
version (Windows)
{
symb = GetProcAddress(m_lib, toStringz(symbolName));
}
version (linux)
{
symb = dlsym(m_lib, toStringz(symbolName));
}
}
if (symb is null)
debug report( "Symbol cannot be found in specified library", m_libPath, symbolName);
return symb;
}
void close()
{
version (Tango)
{
m_lib.unload();
}
else
{
version (Windows)
{
FreeLibrary(m_lib);
}
version (linux)
{
dlclose(m_lib);
}
alreadyLoaded.remove(this.m_libPath);
}
}
static void closeAll()
{
foreach(lib; alreadyLoaded.values)
{
lib.close();
}
}
private:
this(string libraryPath)
{
m_libPath = libraryPath;
version (Tango)
{
m_lib = SharedLib.load(libraryPath);
}
else
{
version (Windows)
{
m_lib = LoadLibraryA(toStringz(libraryPath));
}
version (linux)
{
m_lib = dlopen(toStringz(libraryPath), RTLD_NOW | RTLD_GLOBAL);
}
}
if (m_lib is null)
{
debug report("Cannot open library", m_libPath, null);
version (Windows)
{
debug report("Windows error message: " ~ sysErrorString(GetLastError()), m_libPath, null);
}
}
}
version (Tango)
{
SharedLib m_lib;
}
else
{
MODULEHANDLE m_lib;
}
static DllLoader[string] alreadyLoaded;
string m_libPath;
}