yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1#include "slang-shared-library.h" 2 3#include "slang-com-ptr.h" 4#include "slang-io.h" 5#include "slang-string-util.h" 6 7#if defined(_WIN32 ) 8#include <windows.h> 9#elif defined(__linux__ )|| defined(SLANG_OSX ) 10#include <dlfcn.h> 11#endif 12#include <sys/stat.h> 13#include <sys/types.h> 14#ifndef _WIN32 15#include <unistd.h> 16#endif 17 18namespace Slang 19{ 20 21/* !!!!!!!!!!!!!!!!!!!!!!!!!! DefaultSharedLibraryLoader !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ 22 23/* static */ DefaultSharedLibraryLoader DefaultSharedLibraryLoader ::s_singleton ; 24 25ISlangUnknown * DefaultSharedLibraryLoader ::getInterface (const Guid & guid ) 26{ 27return (guid == ISlangUnknown ::getTypeGuid ()|| 28guid == ISlangSharedLibraryLoader ::getTypeGuid ()) 29 ?static_cast < ISlangSharedLibraryLoader *> (this ) 30 :nullptr ; 31} 32 33SlangResult DefaultSharedLibraryLoader ::loadSharedLibrary ( 34const char * path , 35ISlangSharedLibrary ** outSharedLibrary ) 36{ 37* outSharedLibrary = nullptr ; 38// Try loading 39SharedLibrary ::Handle handle ; 40SLANG_RETURN_ON_FAIL (SharedLibrary ::load (path ,handle )); 41* outSharedLibrary = ComPtr < ISlangSharedLibrary > (new DefaultSharedLibrary (handle )).detach (); 42return SLANG_OK ; 43} 44 45SlangResult DefaultSharedLibraryLoader ::loadPlatformSharedLibrary ( 46const char * path , 47ISlangSharedLibrary ** outSharedLibrary ) 48{ 49* outSharedLibrary = nullptr ; 50// Try loading 51SharedLibrary ::Handle handle ; 52SLANG_RETURN_ON_FAIL (SharedLibrary ::loadWithPlatformPath (path ,handle )); 53* outSharedLibrary = ComPtr < ISlangSharedLibrary > (new DefaultSharedLibrary (handle )).detach (); 54return SLANG_OK ; 55} 56 57/* static */ SlangResult DefaultSharedLibraryLoader ::load ( 58ISlangSharedLibraryLoader * loader , 59const String & path , 60const String & name , 61ISlangSharedLibrary ** outLibrary ) 62{ 63if (path .getLength ()) 64 { 65String combinedPath = Path ::combine (path ,name ); 66return loader -> loadSharedLibrary (combinedPath .getBuffer (),outLibrary ); 67 } 68else 69 { 70return loader -> loadSharedLibrary (name .getBuffer (),outLibrary ); 71 } 72} 73 74/* !!!!!!!!!!!!!!!!!!!!!!!!!! ScopeSharedLibrary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ 75 76ScopeSharedLibrary ::~ScopeSharedLibrary () 77{ 78if (m_sharedLibraryHandle ) 79 { 80// We have to unload if we want to be able to remove 81SharedLibrary ::unload (m_sharedLibraryHandle ); 82m_sharedLibraryHandle = nullptr ; 83 } 84} 85 86/* !!!!!!!!!!!!!!!!!!!!!!!!!! DefaultSharedLibrary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ 87 88DefaultSharedLibrary ::~DefaultSharedLibrary () 89{ 90if (m_sharedLibraryHandle ) 91 { 92SharedLibrary ::unload (m_sharedLibraryHandle ); 93 } 94} 95 96void * DefaultSharedLibrary ::findSymbolAddressByName (char const * name ) 97{ 98return SharedLibrary ::findSymbolAddressByName (m_sharedLibraryHandle ,name ); 99} 100 101void * DefaultSharedLibrary ::castAs (const SlangUUID & guid ) 102{ 103if (auto intf = getInterface (guid )) 104 { 105return intf ; 106 } 107return getObject (guid ); 108} 109 110void * DefaultSharedLibrary ::getInterface (const Guid & guid ) 111{ 112if (guid == ISlangUnknown ::getTypeGuid ()|| guid == ICastable ::getTypeGuid ()|| 113guid == ISlangSharedLibrary ::getTypeGuid ()) 114 { 115return static_cast < ISlangSharedLibrary *> (this ); 116 } 117return nullptr ; 118} 119 120void * DefaultSharedLibrary ::getObject (const Guid & guid ) 121{ 122if (guid == DefaultSharedLibrary ::getTypeGuid ()) 123 { 124return this ; 125 } 126return nullptr ; 127} 128 129/* !!!!!!!!!!!!!!!!!!!!!!!!!! SharedLibraryUtils !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ 130 131String SharedLibraryUtils ::getSharedLibraryFileName (void * symbolInLib ) 132{ 133#if defined(_WIN32 ) 134HMODULE moduleHandle ; 135GetModuleHandleExA ( 136GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT , 137 (LPCSTR )symbolInLib , 138& moduleHandle ); 139const int maxLength = 1024 ; 140wchar_t filenameBuffer [maxLength ]; 141auto length = GetModuleFileNameW (moduleHandle ,filenameBuffer ,maxLength ); 142if (length == maxLength ) 143 { 144// Insufficient buffer, return empty. 145return String (); 146 } 147return String ::fromWString (filenameBuffer ); 148 149#elif defined(__linux__ )|| defined(SLANG_OSX ) 150Dl_info dllInfo ; 151if (!dladdr (symbolInLib ,& dllInfo )) 152 { 153return String (); 154 } 155return dllInfo .dli_fname ; 156 157#else 158return String (); 159#endif 160} 161 162uint64_t SharedLibraryUtils ::getSharedLibraryTimestamp (void * symbolInLib ) 163{ 164auto fileName = getSharedLibraryFileName (symbolInLib ); 165if (fileName .getLength ()== 0 ) 166return 0 ; 167struct stat result ; 168if (stat (fileName .getBuffer (),& result )== 0 ) 169 { 170auto mod_time = result .st_mtime ; 171return (uint64_t )mod_time ; 172 } 173return 0 ; 174} 175 176}// namespace Slang