/*
This file is a part of my game engine,
but you can use it in your projects
without asking permission under MIT license terms.
Copyright (C) 2012 evilrat
*/
module util.sharedlib;
// =========================
// LOADER
// =========================
// this is a class to allow reference counting and easy sharing library handle,
// if you don't like the idea of class overhead just remove unload method from
// destructor and make it struct, but remember about RAII.
//
// note: loading D libraries should work properly only on windows
// at this moment(DMD 2.061)
final class SharedLib
{
public:
~this()
{
Unload();
}
void Load(string libName)
{
version(Posix)
_handle = dlopen(libName.toStringz(), RTLD_NOW);
else
_handle = Runtime.loadLibrary(libName);
}
void Unload()
{
if ( _handle !is null )
{
version(Posix)
dlclose(_handle);
else
Runtime.unloadLibrary(_handle);
}
}
T GetSymbol(T = void*)(string symbolName)
{
version(Posix)
return cast(T)dlsym(_handle, symbolName.toStringz());
else
return cast(T)GetProcAddress(cast(HMODULE)_handle, symbolName.toStringz());
// should never reach this
return null;
}
@property public SharedLibHandle handle() { return _handle; }
private SharedLibHandle _handle;
}
// =========================
// PRIVATE IMPORTS AND DECLARATIONS
// =========================
private
{
import core.runtime;
// handle
alias void* SharedLibHandle;
version(Posix)
{
version(Linux) {
private import std.c.linux.linux;
}
else
{
extern(C)
{
// there are more constants but i use only this.
enum RTLD_NOW = 2;
// prototypes for dynamic loader
void* dlopen(const(char)* file, int mode);
void* dlsym(void* handle, const(char*) name);
const(char)* dlerror();
int dlclose(void* handle);
}
}
}
else version(Windows) {
import std.c.windows.windows;
}
}