From 1185bd464092f372430cbfaa15a7be4dcaa90752 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Tue, 6 Nov 2018 14:28:25 -0500 Subject: Feature/shared library refactor (#712) * * Added ISlangSharedLibraryLoader and ISlangSharedLibrary * Implemented default implementations * Added slang API function to get/set the ISlangSharedLibraryLoader on the session * Put function caching onto the Session - so that if the loader is chaged, its easy to reset the shared libraries, and functions * Run premake. * Fix problem with setting null, would cause an unnecessary function/shared lib flush. * * Unload SharedLibrary when DefaultSharedLibrary is deleted. * Make SharedLibrary handle unload safely if already unloaded. * Refactor SharedLibrary, such that it becomes a utility class - simplifying it's semantics. * Simplified ISlangSharedLibrary such that doesn't have unload and isLoaded so easier to implement. Use updated SharedLibrary impl. * Disable aarch64 on windows * Premake windows files without aarch64 build. * Moved slang-shared-library to core (so can be used in code outside of main slang) Fixed problem in premake5 where on windows projects were incorrectly constructed * Allowed RefObject to base class of com types Added ConfigurableSharedLibraryLoader Added -dxc-path -fxc-path -glslang-path Fix problem with dxc-path not honoring it's path when loading dxil * Added documentation for command line control of dll loading paths. * Remove some tabbing issues. * Change name of include guard. --- source/core/platform.cpp | 144 +++++++++++++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 56 deletions(-) (limited to 'source/core/platform.cpp') diff --git a/source/core/platform.cpp b/source/core/platform.cpp index 374606e4a..b96240def 100644 --- a/source/core/platform.cpp +++ b/source/core/platform.cpp @@ -1,6 +1,8 @@ // platform.cpp #include "platform.h" +#include "common.h" + #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #define NOMINMAX @@ -16,72 +18,102 @@ namespace Slang { // SharedLibrary - SharedLibrary SharedLibrary::load(char const* name) - { - SharedLibrary result; - result.handle = nullptr; +/* static */SlangResult SharedLibrary::load(const char* filename, SharedLibrary::Handle& handleOut) +{ + StringBuilder builder; + appendPlatformFileName(UnownedStringSlice(filename), builder); + return loadWithPlatformFilename(builder.begin(), handleOut); +} #ifdef _WIN32 - { - HMODULE h = LoadLibraryA(name); - result.handle = (Handle) h; - } -#else - { - String fullName; - fullName.append("lib"); - fullName.append(name); - fullName.append(".so"); - - void* h = dlopen(fullName.Buffer(), RTLD_NOW|RTLD_LOCAL); - if(!h) - { - if(auto msg = dlerror()) - { - fprintf(stderr, "error: %s\n", msg); - } - } - result.handle = (Handle) h; - } -#endif +/* static */SlangResult SharedLibrary::loadWithPlatformFilename(char const* platformFileName, SharedLibrary::Handle& handleOut) +{ + handleOut = nullptr; + // https://docs.microsoft.com/en-us/windows/desktop/api/libloaderapi/nf-libloaderapi-loadlibrarya + const HMODULE h = LoadLibraryA(platformFileName); + if (!h) + { + const DWORD lastError = GetLastError(); + switch (lastError) + { + case ERROR_MOD_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + case ERROR_FILE_NOT_FOUND: + { + return SLANG_E_NOT_FOUND; + } + case ERROR_INVALID_ACCESS: + case ERROR_ACCESS_DENIED: + case ERROR_INVALID_DATA: + { + return SLANG_E_CANNOT_OPEN; + } + default: break; + } + // Turn to Result, if not one of the well known errors + return HRESULT_FROM_WIN32(lastError); + } + handleOut = (Handle)h; + return SLANG_OK; +} - return result; - } +/* static */void SharedLibrary::unload(Handle handle) +{ + SLANG_ASSERT(handle); + ::FreeLibrary((HMODULE)handle); +} + +/* static */SharedLibrary::FuncPtr SharedLibrary::findFuncByName(Handle handle, char const* name) +{ + SLANG_ASSERT(handle); + return (FuncPtr)GetProcAddress((HMODULE)handle, name); +} + +/* static */void SharedLibrary::appendPlatformFileName(const UnownedStringSlice& name, StringBuilder& dst) +{ + // Windows doesn't need the extension or any prefix to work + dst.Append(name); +} + +#else // _WIN32 + +/* static */SlangResult SharedLibrary::loadWithPlatformFilename(char const* platformFileName, Handle& handleOut) +{ + handleOut = nullptr; - void SharedLibrary::unload() + void* h = dlopen(platformFileName, RTLD_NOW | RTLD_LOCAL); + if(!h) { -#ifdef _WIN32 + if(auto msg = dlerror()) { - FreeLibrary( - (HMODULE) handle); + fprintf(stderr, "error: %s\n", msg); } -#else - { - dlclose(handle); - } -#endif - + return SLANG_FAIL; } + handleOut = (Handle)h; + return SLANG_OK; +} - SharedLibrary::FuncPtr SharedLibrary::findFuncByName(char const* name) - { - FuncPtr funcPtr = nullptr; +/* static */void SharedLibrary::unload(Handle handle) +{ + SLANG_ASSERT(handle); + dlclose(handle); +} -#ifdef _WIN32 - { - funcPtr = (FuncPtr) GetProcAddress( - (HMODULE) handle, - name); - } -#else - { - funcPtr = (FuncPtr) dlsym( - (void*) handle, - name); - } -#endif +/* static */SharedLibrary::FuncPtr SharedLibrary::findFuncByName(Handle handle, char const* name) +{ + SLANG_ASSERT(handle); + return (FuncPtr)dlsym((void*)handle, name); +} + +/* static */void SharedLibrary::appendPlatformFileName(const UnownedStringSlice& name, StringBuilder& dst) +{ + dst.Append("lib"); + dst.Append(name); + dst.Append(".so"); +} + +#endif // _WIN32 - return funcPtr; - } } \ No newline at end of file -- cgit v1.2.3