Docs: What is an "Assembly qualified delegate type name"?

Created on 13 Jan 2020  Â·  11Comments  Â·  Source: dotnet/docs

Does this provide me a way to specify the function signature of the C# method?

What would an example of this parameter look like?

https://github.com/dotnet/samples/blob/master/core/hosting/HostWithHostFxr/src/NativeHost/nativehost.cpp#L104


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Area - .NET Core Guide product-question

All 11 comments

Ah, it looks like I need to fallback on the CoreClrHost API:

https://github.com/dotnet/runtime/blob/master/src/coreclr/src/hosts/inc/coreclrhost.h#L79-L99

Still interested in the answer to the original question, though.

I'll ping the author on email.

Regarding the original question, yes, my understanding is that HostFxr allows specifying a particular overload of a managed method by giving the (assembly-qualified) name of a delegate defining the method signature (as opposed to hosting with CoreClrHost.h, which only looks up managed entry points by method name).

You should be able to just provide a string containing the assembly-qualified name of the delegate type matching your entry point's signature (including, perhaps, marshaling attributes).

cc'ing @vitek-karas to confirm this, though, because I'm not very experienced with HostFxr.

The code which consumes that string is here: https://github.com/dotnet/runtime/blob/eb95163a0880cac1ba127b81e3cb753e5a65f8cc/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComponentActivator.cs#L64

If you specify null it defaults to the `ComponentEntryPoint delegate: https://github.com/dotnet/runtime/blob/eb95163a0880cac1ba127b81e3cb753e5a65f8cc/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComponentActivator.cs#L19

If you specify a value, it is effectively passed to Type.GetType(yourValue, ...): https://github.com/dotnet/runtime/blob/eb95163a0880cac1ba127b81e3cb753e5a65f8cc/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComponentActivator.cs#L114

It should be assembly qualified to avoid possible issues with duplicate type names across assemblies, but in reality it's not enforced.

As @mjrousos noted this lets you declare the method signature via declaring a delegate type in C#. The added benefit is that you can use marshalling attributes in the delegate if necessary.

So I should be able to invoke this:

```c#
namespace SamplePrecompiledAssembly {
public static class Startup {
public static Func> Func(string code) { // <--


Like this?:

```c++
returnCode = load_assembly_and_get_function_pointer_fn(loadAssemblyAndGetFunctionPointer)(
    assemblyPath.c_str(),
    assemblyQualifiedTypeName.c_str(),
    methodName.c_str(),
    std::string("SamplePrecompiledAssembly.Startup+Func, SamplePrecompiledAssembly").c_str(), // <--
    nullptr,
    reinterpret_cast<void **>(&run));

The string should point to a delegate type, not a method. So something like this should work:
``` C#
namespace SamplePrecompiledAssembly {
public static class Startup {
public delegate Func> MyFuncDelegate(string);

    public static Func<object, Task<object>> Func(string code) { 
            }
    }

}
```

And then you should be able to use:
SamplePrecompiledAssembly.Startup.MyFuncDelegate as the string for the function.

Note that given this sample it may not work as I don't know how the interop would marshal a Func<,> to native code. And even if it did manage to do that, there would be no way from the native code to operate on Task<object>.

Hmm, I'm beginning to think this might be a product bug.

Steps to Reproduce:

git clone https://github.com/brianjenkins94/Run-DNC.git
cd Run-DNC
npm install
npm build # For whatever reason on Windows you just need to keep building through errors about architecture mismatches and errors writing to the program database.
npm start

Output on Windows 10:

> [email protected] start C:\Users\User\Documents\GitHub\Run-DNC
> node test.js

get_hostfxr_path() = 0
hostfxr_initialize_for_runtime_config_fn() = 0
hostfxr_get_runtime_delegate_fn() = 0
hostfxr_close_fn() = 0

assembly_path = "C:\\Users\\User\\Documents\\GitHub\\Run-DNC\\src\\SamplePrecompiledAssembly\\bin\\Debug\\netstandard2.1\\SamplePrecompiledAssembly.dll"
type_name = SamplePrecompiledAssembly.Startup, SamplePrecompiledAssembly
method_name = Invoke
delegate_type_name = SamplePrecompiledAssembly.Startup.InvokeDelegate, SamplePrecompiledAssembly

load_assembly_and_get_function_pointer_fn() = 0
run() = 0

Output on macOS 10.15 and Ubuntu 18.04:

> [email protected] start /Users/bjenks/Sites/Run-DNC
> node test.js

get_hostfxr_path() = 0
hostfxr_initialize_for_runtime_config_fn() = 0
hostfxr_get_runtime_delegate_fn() = 0
hostfxr_close_fn() = 0

assembly_path = "/Users/bjenks/Sites/Run-DNC/src/SamplePrecompiledAssembly/bin/Debug/netstandard2.1/SamplePrecompiledAssembly.dll"
type_name = SamplePrecompiledAssembly.Startup, SamplePrecompiledAssembly
method_name = Invoke
delegate_type_name = SamplePrecompiledAssembly.Startup.InvokeDelegate, SamplePrecompiledAssembly

load_assembly_and_get_function_pointer_fn() = -2146233054
run() = zsh: segmentation fault

So it's working on Windows, but not on Mac or Linux.

Where would be the appropriate place to pursue this? Since I assume docs isn't it.

I didn't try to run it, but looking at the code there's a difference between Windows and Linux/Mac - when you're calling the load_assembly_and_get_function_pointer you pass the delegate type name in the Linux/Mac path, but not in the Windows path. Also the output above doesn't seem to match the code in the repo: The code in the repo would specify SamplePrecompiledAssembly.InvokeDelegate as the delegate type name (without the Startup) but the output above has it - so maybe you have local fixes?

The error code is COR_E_TYPELOAD - this would happen if the call Type.GetType(delegateTypeName) failed.

I made those fixes and it works now.

Thank you very much for your help and patience.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sebagomez picture sebagomez  Â·  3Comments

Eilon picture Eilon  Â·  3Comments

ike86 picture ike86  Â·  3Comments

stjepan picture stjepan  Â·  3Comments

svick picture svick  Â·  3Comments