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

API: Native Library Resolve Event #27647

Closed
swaroop-sridhar opened this issue Oct 16, 2018 · 12 comments
Closed

API: Native Library Resolve Event #27647

swaroop-sridhar opened this issue Oct 16, 2018 · 12 comments
Assignees
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime.InteropServices
Milestone

Comments

@swaroop-sridhar
Copy link
Contributor

This proposal adds a Native library resolving event, to be raised when the runtime cannot resolve a native library load.

Proposed API

namespace System.Runtime.Loader
{
    public abstract class AssemblyLoadContext
    {
        /// Event handler for resolving native libraries
        /// Inputs: Invoking assembly, and library name to resolve
        /// Returns: A handle to the loaded native library
        public event Func<Assembly, string, IntPtr> ResolvingUnmanagedDll;
    }
}

Rationale

In the case of Loading assemblies, the runtime provides the application to customize the load at various phases:

This proposal creates a matching facility for unmanaged libraries

In particular, the NativeLibraryResolve event is expected to provide flexibility for running custom native library resolution logic from plugins. Hence the motivation to have the event per AssemblyLoadContext, rather than globally.

DllImport sequence

DllImport load library works in the following order, stop at any step the library is successfully loaded.

  • If the invoking-assembly has a DllImportResolver callback registered, invoke it.
  • If the invoking-assembly is not in the default load context, call AssemblyLoadContext.LoadUnmanagedDll()
  • Run the default load logic, try loading from:
    • AppDomain cache
    • NATIVE_DLL_SEARCH_DIRECTORIES
    • Invoking-assembly directory, System32, etc. based on DllImportSearchPaths
  • Raise the ResolvingUnmanagedDll event

Discussion

Alternate notation

In this proposal ResolvingUnmanagedDll uses Func notation in order to be consistent with the
Loading/Unloading events in AssemblyLoadContext.

An alternative is to use EventHandler style recommended by these guidelines, and similar to certain other events in the same class.

namespace System
{
    public delegate IntPtr UnmanagedDllResolveEventHandler(object sender, ResolveEventArgs args);
}

namespace System.Runtime.Loader
{
    public abstract class AssemblyLoadContext
    {
        public event UnmanagedDllResolveEventHandler ResolvingUnmanagedDll;
    }
}

Related Topics

dotnet/corefx#32015 Native Library Loader API

@swaroop-sridhar swaroop-sridhar self-assigned this Oct 16, 2018
@swaroop-sridhar
Copy link
Contributor Author

@jkotas
Copy link
Member

jkotas commented Oct 16, 2018

ResolveEventHandler returns Assembly. This should have a different type.

@swaroop-sridhar
Copy link
Contributor Author

Thanks @jkotas, I've fixed it now.

@jkotas
Copy link
Member

jkotas commented Oct 16, 2018

The existing events on AssemblyLoadContext use Action/Func. Do we want to follow the same style?

@swaroop-sridhar
Copy link
Contributor Author

In AssemblyLoadContext, the Loading/Unloading events use the Func notation, while others use EventHandler style.

I wrote in event in the EventHandler style following these guidelines.
I'm happy to write this event in the Func style, in fact, I'd prefer it for this case.

@vitek-karas
Copy link
Member

I'm worried about naming consistency. On managed side we have Load/Resolving. On native we have LoadUnmanagedDll/NativeLibraryResolve. To be 100% consistent we should call it ResolvingUnmanagedDll.

@vitek-karas
Copy link
Member

I think it's important to mention that there are 2 reasons to add this:

  • Plugins - which don't want to register callbacks for every assembly in the plugin as that creates problems with multiple callbacks support.
  • Anybody (Plugins included) - as this will be the only way (excluding callbacks) to provide custom resolution of native libraries in the Default context.

@vitek-karas
Copy link
Member

I also think it would be a good idea to describe the proposed ordering of the various hooks. It starts with a call to a DllImport method - what are the high-level steps and where/when are the various hooks called.

@AaronRobinsonMSFT
Copy link
Member

what are the high-level steps and where/when are the various hooks called.

Following on to @vitek-karas's comment, the official guidance for DllImport should be updated with these newdetails.

@swaroop-sridhar
Copy link
Contributor Author

I've updated the naming, and added a section on DllImport order.

@swaroop-sridhar
Copy link
Contributor Author

swaroop-sridhar commented Oct 18, 2018

the official guidance for DllImport should be updated with these newdetails.

Sure, once the feature is checked in/released, we should update it.

swaroop-sridhar referenced this issue in swaroop-sridhar/coreclr Jan 10, 2019
This change adds the Native library resolving event,
to be raised when the runtime cannot resolve a native library load.

```C#
namespace System.Runtime.Loader
{
    public abstract class AssemblyLoadContext
    {
        public event Func<Assembly, string, IntPtr> ResolvingUnmanagedDll;
    }
}
```

With this change, the DllImport resolution sequence is as follows:
(stopping at any step the library is successfully loaded)

If the invoking-assembly is not in the default load context, call AssemblyLoadContext.LoadUnmanagedDll()
Run the default load logic, try loading from:
  AppDomain cache
  NATIVE_DLL_SEARCH_DIRECTORIES
  Invoking-assembly directory, System32, etc. based on DllImportSearchPaths
Raise the ResolvingUnmanagedDll event

API Review: https://github.com/dotnet/corefx/issues/32850
swaroop-sridhar referenced this issue in swaroop-sridhar/coreclr Jan 10, 2019
This change adds the Native library resolving event, to be raised as the last attempt to resolve a native DLL in an AssemblyLoadContext.

With this change, the DllImport resolution sequence is as follows (stopping at any step with successful resolution):

* If the invoking-assembly is not in the default load context, call AssemblyLoadContext.LoadUnmanagedDll()
* Run the default load logic, try loading from:
    * AppDomain cache
    * NATIVE_DLL_SEARCH_DIRECTORIES
    * Invoking-assembly directory, System32, etc. based on DllImportSearchPaths
* Raise the ResolvingUnmanagedDll event

API Review: https://github.com/dotnet/corefx/issues/32850
swaroop-sridhar referenced this issue in swaroop-sridhar/coreclr Jan 10, 2019
This change adds the Native library resolving event, to be raised as the last attempt to resolve a native DLL in an AssemblyLoadContext.

With this change, the DllImport resolution sequence is as follows (stopping at any step with successful resolution):

* If the invoking-assembly is not in the default load context, call AssemblyLoadContext.LoadUnmanagedDll()
* Run the default load logic, try loading from:
    * AppDomain cache
    * NATIVE_DLL_SEARCH_DIRECTORIES
    * Invoking-assembly directory, System32, etc. based on DllImportSearchPaths
* Raise the ResolvingUnmanagedDll event

API Review: https://github.com/dotnet/corefx/issues/32850
swaroop-sridhar referenced this issue in swaroop-sridhar/coreclr Jan 10, 2019
This change adds the Native library resolving event, to be raised as the last attempt to resolve a native DLL in an AssemblyLoadContext.

With this change, the DllImport resolution sequence is as follows (stopping at any step with successful resolution):

* If the invoking-assembly is not in the default load context, call AssemblyLoadContext.LoadUnmanagedDll()
* Run the default load logic, try loading from:
    * AppDomain cache
    * NATIVE_DLL_SEARCH_DIRECTORIES
    * Invoking-assembly directory, System32, etc. based on DllImportSearchPaths
* Raise the ResolvingUnmanagedDll event

API Review: https://github.com/dotnet/corefx/issues/32850
swaroop-sridhar referenced this issue in swaroop-sridhar/coreclr Jan 12, 2019
This change adds the Native library resolving event, to be raised as the last attempt to resolve a native DLL in an AssemblyLoadContext.

With this change, the DllImport resolution sequence is as follows (stopping at any step with successful resolution):

* If the invoking-assembly is not in the default load context, call AssemblyLoadContext.LoadUnmanagedDll()
* Run the default load logic, try loading from:
    * AppDomain cache
    * NATIVE_DLL_SEARCH_DIRECTORIES
    * Invoking-assembly directory, System32, etc. based on DllImportSearchPaths
* Raise the ResolvingUnmanagedDll event

API Review: https://github.com/dotnet/corefx/issues/32850

The ResolveEventTests triggered a pre-existing bug in the exception handling code (#21964).
Disabling the test on ARM64 Windows until the issue is fixed.
swaroop-sridhar referenced this issue in swaroop-sridhar/coreclr Jan 12, 2019
This change adds the Native library resolving event, to be raised as the last attempt to resolve a native DLL in an AssemblyLoadContext.

With this change, the DllImport resolution sequence is as follows (stopping at any step with successful resolution):

* If the invoking-assembly is not in the default load context, call AssemblyLoadContext.LoadUnmanagedDll()
* Run the default load logic, try loading from:
    * AppDomain cache
    * NATIVE_DLL_SEARCH_DIRECTORIES
    * Invoking-assembly directory, System32, etc. based on DllImportSearchPaths
* Raise the ResolvingUnmanagedDll event

API Review: https://github.com/dotnet/corefx/issues/32850

The ResolveEventTests triggered a pre-existing bug in the exception handling code (#21964).
Disabling the test on ARM64 Windows until the issue is fixed.
swaroop-sridhar referenced this issue in dotnet/coreclr Jan 13, 2019
This change adds the Native library resolving event, to be raised as the last attempt to resolve a native DLL in an AssemblyLoadContext.

With this change, the DllImport resolution sequence is as follows (stopping at any step with successful resolution):

* If the invoking-assembly is not in the default load context, call AssemblyLoadContext.LoadUnmanagedDll()
* Run the default load logic, try loading from:
    * AppDomain cache
    * NATIVE_DLL_SEARCH_DIRECTORIES
    * Invoking-assembly directory, System32, etc. based on DllImportSearchPaths
* Raise the ResolvingUnmanagedDll event

API Review: https://github.com/dotnet/corefx/issues/32850

The ResolveEventTests triggered a pre-existing bug in the exception handling code (#21964).
Disabling the test on ARM64 Windows until the issue is fixed.
swaroop-sridhar referenced this issue in swaroop-sridhar/coreclr Jan 14, 2019
This change adds the Native library resolving event, to be raised as the last attempt to resolve a native DLL in an AssemblyLoadContext.

With this change, the DllImport resolution sequence is as follows (stopping at any step with successful resolution):

* If the invoking-assembly is not in the default load context, call AssemblyLoadContext.LoadUnmanagedDll()
* Run the default load logic, try loading from:
    * AppDomain cache
    * NATIVE_DLL_SEARCH_DIRECTORIES
    * Invoking-assembly directory, System32, etc. based on DllImportSearchPaths
* Raise the ResolvingUnmanagedDll event

API Review: https://github.com/dotnet/corefx/issues/32850

The ResolveEventTests triggered a pre-existing bug in the exception handling code (#21964).
Disabling the test on ARM64 Windows until the issue is fixed.
@jeffschwMSFT
Copy link
Member

Closed with dotnet/corefx#34668

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 3.0 milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime.InteropServices
Projects
None yet
Development

No branches or pull requests

6 participants