Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load plugins using LoadLibraryEx with LOAD_WITH_ALTERED_SEARCH_PATH on Windows #2368

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from

Conversation

SimonBoorer
Copy link

@SimonBoorer SimonBoorer commented Mar 29, 2023

Description of Change(s)

Search for USD plugin dependencies in the folder that the plugin is loaded from as well as the application's directory on Windows. This is to support situations where USD itself is a plugin for an application. See #2367 for more information.

I found when testing LoadLibraryEx that the LOAD_WITH_ALTERED_SEARCH_PATH flag only works when using back slashes instead of forward slashes, so I've added a ArchWindowsPreferredPath method to convert between them based off of std::filesystem::path::make_preferred in C++17.

This limitation is mentioned here:

If the string specifies a fully qualified path, the function searches only that path for the module. When specifying a path, be sure to use backslashes (\), not forward slashes (/).

I originally added ArchPreferredPath that simply returned the input path for MacOS/Linux but decided against the extra copy.

I also made converting to back slashes the responsibility of the caller (PlugPlugin::_Load) rather than ArchLibraryOpen in keeping with LoadLibraryEx.

Happy to revisit either of these decisions.

Fixes Issue(s)

#2367

  • I have verified that all unit tests pass with the proposed changes
  • I have submitted a signed Contributor License Agreement

@sunyab
Copy link
Contributor

sunyab commented Mar 31, 2023

Filed as internal issue #USD-8175

Copy link
Contributor

@sunyab sunyab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @SimonBoorer, I left some notes but it's just some reorganization of what you've already got. Let me know what you think, thanks!

Comment on lines +257 to +261
#if defined(ARCH_OS_WINDOWS)
_handle = TfDlopen(ArchWindowsPreferredPath(_path).c_str(), ARCH_LIBRARY_ALTERED_SEARCH_PATH, &dsoError);
#else
_handle = TfDlopen(_path.c_str(), ARCH_LIBRARY_NOW, &dsoError);
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having an #ifdef here I think it'd be simpler to have the one function call and just combine ARCH_LIBRARY_NOW | ARCH_LIBRARY_ALTERED_SEARCH_PATH since these are already set to platform-specific values in arch/library.h.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add a comment about how ARCH_LIBRARY_ALTERED_SEARCH_PATH on Windows ensures that .dll dependencies in the same directory as the specified library will be picked up without requiring modifications to the environment?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I just noticed TfDlopen takes a std::string and not a const char*, so if you could drop the .c_str() while you're here that'd be great

@@ -44,7 +44,7 @@ void* ArchLibraryOpen(const std::string &filename, int flag)
{
#if defined(ARCH_OS_WINDOWS)
arch_lastLibraryError = 0;
if (void* result = LoadLibrary(filename.c_str())) {
if (void* result = LoadLibraryEx(filename.c_str(), NULL, flag)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly enough the docs for the old LoadLibrary mention the same backslash requirement -- I guess it just didn't make an actual difference until this change.

In any case, if we follow the letter of the docs then the filename we pass to LoadLibraryEx must always use backslashes, so I'd advocate for doing the conversion to preferred path here. That way, the logic is centralized and downstream code wouldn't have to be platform-aware. Does that sound OK?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants