123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- /* -----------------------------------------------------------------------------
- * wrapperloader.swg
- *
- * Support code for dynamically linking the C wrapper library from the D
- * wrapper module.
- *
- * The loading code was adapted from the Derelict project and is used with
- * permission from Michael Parker, the original author.
- * ----------------------------------------------------------------------------- */
- %pragma(d) wrapperloadercode = %{
- private {
- version(linux) {
- version = Nix;
- } else version(darwin) {
- version = Nix;
- } else version(OSX) {
- version = Nix;
- } else version(FreeBSD) {
- version = Nix;
- version = freebsd;
- } else version(freebsd) {
- version = Nix;
- } else version(Unix) {
- version = Nix;
- } else version(Posix) {
- version = Nix;
- }
- version(Tango) {
- static import tango.stdc.string;
- static import tango.stdc.stringz;
- version (PhobosCompatibility) {
- } else {
- alias char[] string;
- alias wchar[] wstring;
- alias dchar[] dstring;
- }
- } else {
- version(D_Version2) {
- static import std.conv;
- }
- static import std.string;
- static import std.c.string;
- }
- version(D_Version2) {
- mixin("alias const(char)* CCPTR;");
- } else {
- alias char* CCPTR;
- }
- CCPTR swigToCString(string str) {
- version(Tango) {
- return tango.stdc.stringz.toStringz(str);
- } else {
- return std.string.toStringz(str);
- }
- }
- string swigToDString(CCPTR cstr) {
- version(Tango) {
- return tango.stdc.stringz.fromStringz(cstr);
- } else {
- version(D_Version2) {
- mixin("return std.conv.to!string(cstr);");
- } else {
- return std.c.string.toString(cstr);
- }
- }
- }
- }
- class SwigSwigSharedLibLoadException : Exception {
- this(in string[] libNames, in string[] reasons) {
- string msg = "Failed to load one or more shared libraries:";
- foreach(i, n; libNames) {
- msg ~= "\n\t" ~ n ~ " - ";
- if(i < reasons.length)
- msg ~= reasons[i];
- else
- msg ~= "Unknown";
- }
- super(msg);
- }
- }
- class SwigSymbolLoadException : Exception {
- this(string SwigSharedLibName, string symbolName) {
- super("Failed to load symbol " ~ symbolName ~ " from shared library " ~ SwigSharedLibName);
- _symbolName = symbolName;
- }
- string symbolName() {
- return _symbolName;
- }
- private:
- string _symbolName;
- }
- private {
- version(Nix) {
- version(freebsd) {
- // the dl* functions are in libc on FreeBSD
- }
- else {
- pragma(lib, "dl");
- }
- version(Tango) {
- import tango.sys.Common;
- } else version(linux) {
- import std.c.linux.linux;
- } else {
- extern(C) {
- const RTLD_NOW = 2;
- void *dlopen(CCPTR file, int mode);
- int dlclose(void* handle);
- void *dlsym(void* handle, CCPTR name);
- CCPTR dlerror();
- }
- }
- alias void* SwigSharedLibHandle;
- SwigSharedLibHandle swigLoadSharedLib(string libName) {
- return dlopen(swigToCString(libName), RTLD_NOW);
- }
- void swigUnloadSharedLib(SwigSharedLibHandle hlib) {
- dlclose(hlib);
- }
- void* swigGetSymbol(SwigSharedLibHandle hlib, string symbolName) {
- return dlsym(hlib, swigToCString(symbolName));
- }
- string swigGetErrorStr() {
- CCPTR err = dlerror();
- if (err is null) {
- return "Unknown Error";
- }
- return swigToDString(err);
- }
- } else version(Windows) {
- alias ushort WORD;
- alias uint DWORD;
- alias CCPTR LPCSTR;
- alias void* HMODULE;
- alias void* HLOCAL;
- alias int function() FARPROC;
- struct VA_LIST {}
- extern (Windows) {
- HMODULE LoadLibraryA(LPCSTR);
- FARPROC GetProcAddress(HMODULE, LPCSTR);
- void FreeLibrary(HMODULE);
- DWORD GetLastError();
- DWORD FormatMessageA(DWORD, in void*, DWORD, DWORD, LPCSTR, DWORD, VA_LIST*);
- HLOCAL LocalFree(HLOCAL);
- }
- DWORD MAKELANGID(WORD p, WORD s) {
- return (((cast(WORD)s) << 10) | cast(WORD)p);
- }
- enum {
- LANG_NEUTRAL = 0,
- SUBLANG_DEFAULT = 1,
- FORMAT_MESSAGE_ALLOCATE_BUFFER = 256,
- FORMAT_MESSAGE_IGNORE_INSERTS = 512,
- FORMAT_MESSAGE_FROM_SYSTEM = 4096
- }
- alias HMODULE SwigSharedLibHandle;
- SwigSharedLibHandle swigLoadSharedLib(string libName) {
- return LoadLibraryA(swigToCString(libName));
- }
- void swigUnloadSharedLib(SwigSharedLibHandle hlib) {
- FreeLibrary(hlib);
- }
- void* swigGetSymbol(SwigSharedLibHandle hlib, string symbolName) {
- return GetProcAddress(hlib, swigToCString(symbolName));
- }
- string swigGetErrorStr() {
- DWORD errcode = GetLastError();
- LPCSTR msgBuf;
- DWORD i = FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- null,
- errcode,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- cast(LPCSTR)&msgBuf,
- 0,
- null);
- string text = swigToDString(msgBuf);
- LocalFree(cast(HLOCAL)msgBuf);
- if (i >= 2) {
- i -= 2;
- }
- return text[0 .. i];
- }
- } else {
- static assert(0, "Operating system not supported by the wrapper loading code.");
- }
- final class SwigSharedLib {
- void load(string[] names) {
- if (_hlib !is null) return;
- string[] failedLibs;
- string[] reasons;
- foreach(n; names) {
- _hlib = swigLoadSharedLib(n);
- if (_hlib is null) {
- failedLibs ~= n;
- reasons ~= swigGetErrorStr();
- continue;
- }
- _name = n;
- break;
- }
- if (_hlib is null) {
- throw new SwigSwigSharedLibLoadException(failedLibs, reasons);
- }
- }
- void* loadSymbol(string symbolName, bool doThrow = true) {
- void* sym = swigGetSymbol(_hlib, symbolName);
- if(doThrow && (sym is null)) {
- throw new SwigSymbolLoadException(_name, symbolName);
- }
- return sym;
- }
- void unload() {
- if(_hlib !is null) {
- swigUnloadSharedLib(_hlib);
- _hlib = null;
- }
- }
- private:
- string _name;
- SwigSharedLibHandle _hlib;
- }
- }
- static this() {
- string[] possibleFileNames;
- version (Posix) {
- version (OSX) {
- possibleFileNames ~= ["lib$wraplibrary.dylib", "lib$wraplibrary.bundle"];
- }
- possibleFileNames ~= ["lib$wraplibrary.so"];
- } else version (Windows) {
- possibleFileNames ~= ["$wraplibrary.dll", "lib$wraplibrary.so"];
- } else {
- static assert(false, "Operating system not supported by the wrapper loading code.");
- }
- auto library = new SwigSharedLib;
- library.load(possibleFileNames);
- string bindCode(string functionPointer, string symbol) {
- return functionPointer ~ " = cast(typeof(" ~ functionPointer ~
- "))library.loadSymbol(`" ~ symbol ~ "`);";
- }
- //#if !defined(SWIG_D_NO_EXCEPTION_HELPER)
- mixin(bindCode("swigRegisterExceptionCallbacks$module", "SWIGRegisterExceptionCallbacks_$module"));
- //#endif // SWIG_D_NO_EXCEPTION_HELPER
- //#if !defined(SWIG_D_NO_STRING_HELPER)
- mixin(bindCode("swigRegisterStringCallback$module", "SWIGRegisterStringCallback_$module"));
- //#endif // SWIG_D_NO_STRING_HELPER
- $wrapperloaderbindcode
- }
- //#if !defined(SWIG_D_NO_EXCEPTION_HELPER)
- extern(C) void function(
- SwigExceptionCallback exceptionCallback,
- SwigExceptionCallback illegalArgumentCallback,
- SwigExceptionCallback illegalElementCallback,
- SwigExceptionCallback ioCallback,
- SwigExceptionCallback noSuchElementCallback) swigRegisterExceptionCallbacks$module;
- //#endif // SWIG_D_NO_EXCEPTION_HELPER
- //#if !defined(SWIG_D_NO_STRING_HELPER)
- extern(C) void function(SwigStringCallback callback) swigRegisterStringCallback$module;
- //#endif // SWIG_D_NO_STRING_HELPER
- %}
- %pragma(d) wrapperloaderbindcommand = %{
- mixin(bindCode("$function", "$symbol"));%}
|