Skip to content

[native] Better p/invoke handling when loading foreign libraries #10165

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

Merged
merged 4 commits into from
Jun 5, 2025

Conversation

grendello
Copy link
Contributor

@grendello grendello commented Jun 3, 2025

Improve looking for "foreign" libraries when resolving a p/invoke symbol.

Foreign libraries are those which either aren't contained in the application APK
or which reside on the device in a system location. In such cases, we must attempt
to load the library using its name passed from the managed code (which uses the
DllImport attribute to name the library).

Since DllImport doesn't usually use full name of the target library (e.g. instead
of liblog.so it will use either liblog or log), we must modify the library
name so that the dlopen(3) call can find it on the filesystem. We must make sure
that the library name follows the libNAME.so convention before attempting to load
the library from filesystem..

This is an interim fix for us not finding e.g. the liblog.so library when the
[DllImport("liblog")] attribute is used in the managed code. The library resolution
and reloading system must be redesigned, which will happen in a separate PR as it is
currently not the highest priority task.

@grendello grendello changed the title Dev/grendel/clr better pinvoke foreign libs [native] Better p/invoke handling when loading foreign libraries Jun 3, 2025
@grendello grendello force-pushed the dev/grendel/clr-better-pinvoke-foreign-libs branch from d80648e to 61b8ee2 Compare June 4, 2025 07:11
@grendello grendello force-pushed the dev/grendel/clr-better-pinvoke-foreign-libs branch from 61b8ee2 to 2ef0038 Compare June 5, 2025 07:49
@grendello grendello marked this pull request as ready for review June 5, 2025 07:51
@grendello grendello marked this pull request as draft June 5, 2025 08:01
@grendello grendello marked this pull request as ready for review June 5, 2025 08:17
@grendello grendello requested a review from Copilot June 5, 2025 09:32
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR improves the handling of foreign libraries loaded via p/invoke by ensuring that library names match the expected system naming conventions. Key changes include:

  • Adding an ends_with() utility function to check string suffixes in the runtime-base strings utilities.
  • Simplifying the library path resolution logic in AndroidSystem and updating DSO loading via a templated monodroid_dlopen.
  • Introducing a new constant DSO_PREFIX and a utility function to detect directory components in paths.

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/native/common/include/runtime-base/strings.hh Added an ends_with() helper for string suffix checking.
src/native/clr/runtime-base/android-system.cc Refactored library path resolution and suffix handling.
src/native/clr/include/runtime-base/util.hh Added a utility to check for directory separators in paths.
src/native/clr/include/runtime-base/monodroid-dl.hh Updated monodroid_dlopen to a templated version using a flag.
src/native/clr/include/host/pinvoke-override.hh Adjusted p/invoke override to use the new templated API.
src/native/clr/include/constants.hh Introduced DSO_PREFIX for consistent library name handling.
Comments suppressed due to low confidence (1)

src/native/clr/include/runtime-base/monodroid-dl.hh:109

  • [nitpick] Consider adding a clarifying comment explaining the purpose and expected usage of the template parameter PREFER_AOT_CACHE to aid future maintainers in understanding this API change.
template<bool PREFER_AOT_CACHE> [[gnu::flatten]]

return false;
}

return memcmp (buffer.get () + (length () - s.length ()), s.data (), s.length ()) == 0;
Copy link
Member

Choose a reason for hiding this comment

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

Just for me to understand, length() is always inlined, so no problem with calling it multiple times in an expression?

[[gnu::always_inline]]
auto length () const noexcept -> size_t

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, it's fully inlined each time it's called (which can also the be further optimized by common sub-expression elimination and other techniques, depending on context)

@grendello grendello merged commit 9f8e3d4 into main Jun 5, 2025
59 checks passed
@grendello grendello deleted the dev/grendel/clr-better-pinvoke-foreign-libs branch June 5, 2025 16:36
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