yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Ellie Hermaszewskaformatf65d756bf

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