nvidia/vfx: Prefer AddDllDirectory over SetDefaultDllDirectories

This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2021-10-24 14:18:32 +02:00
parent 6983be457a
commit 26d854b7ce
2 changed files with 58 additions and 23 deletions

View file

@ -63,11 +63,19 @@ streamfx::nvidia::vfx::vfx::~vfx()
{
D_LOG_DEBUG("Finalizing... (Addr: 0x%" PRIuPTR ")", this);
#ifdef WIN32
// Remove the DLL directory from the library loader paths.
if (_extra != nullptr) {
RemoveDllDirectory(reinterpret_cast<DLL_DIRECTORY_COOKIE>(_extra));
}
#endif
{ // The library may need to release Graphics and CUDA resources.
auto gctx = ::streamfx::obs::gs::context();
auto cctx = ::streamfx::nvidia::cuda::obs::get()->get_context()->enter();
_library.reset();
}
}
streamfx::nvidia::vfx::vfx::vfx()
{
@ -110,32 +118,56 @@ streamfx::nvidia::vfx::vfx::vfx()
throw std::runtime_error("Failed to load '" LIB_NAME "'.");
}
// Try and load the library.
{
#ifdef WIN32
// On platforms where it is possible, modify the linker directories.
SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
DLL_DIRECTORY_COOKIE ck = AddDllDirectory(sdk_path.wstring().c_str());
_extra = reinterpret_cast<void*>(ck);
if (ck == 0) {
DWORD ec = GetLastError();
std::string error;
{
LPWSTR str;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, ec, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
reinterpret_cast<LPWSTR>(&str), 0, nullptr);
error = ::streamfx::util::platform::native_to_utf8(std::wstring(str));
LocalFree(str);
}
D_LOG_WARNING("Failed to add '%'s to the library loader paths with error: %s (Code %" PRIu32 ")",
sdk_path.string().c_str(), error.c_str(), ec);
}
#endif
// Try and load the libraries
if (!_library) {
// Load it by name.
std::filesystem::path paths[] = {
LIB_NAME,
util::platform::native_to_utf8(std::filesystem::path(sdk_path) / LIB_NAME),
};
for (auto path : paths) {
try {
_library = ::streamfx::util::library::load(std::string_view(LIB_NAME));
} catch (...) {
// Load it by path.
auto lib_path = sdk_path;
lib_path /= LIB_NAME;
try {
_library = ::streamfx::util::library::load(util::platform::native_to_utf8(lib_path));
_library = ::streamfx::util::library::load(path);
} catch (std::exception const& ex) {
D_LOG_ERROR("Failed to load '%s' from '%s' with error: %s", LIB_NAME,
util::platform::native_to_utf8(lib_path).string().c_str(), ex.what());
throw std::runtime_error("Failed to load '" LIB_NAME "'.");
D_LOG_ERROR("Failed to load '%s' with error: %s", path.string().c_str(), ex.what());
} catch (...) {
D_LOG_ERROR("Failed to load '%s' from '%s'.", LIB_NAME,
util::platform::native_to_utf8(lib_path).string().c_str());
throw std::runtime_error("Failed to load '" LIB_NAME "'.");
D_LOG_ERROR("Failed to load '%s'.", path.string().c_str());
}
if (_library) {
break;
}
}
if (!_library) {
#ifdef WIN32
// Remove the DLL directory from the library loader paths.
if (_extra != nullptr) {
RemoveDllDirectory(reinterpret_cast<DLL_DIRECTORY_COOKIE>(_extra));
}
#endif
throw std::runtime_error("Failed to load " LIB_NAME ".");
}
}

View file

@ -62,6 +62,9 @@ namespace streamfx::nvidia::vfx {
class vfx {
std::shared_ptr<::streamfx::util::library> _library;
#ifdef WIN32
void* _extra;
#endif
std::filesystem::path _model_path;
public: