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

Using load_assembly_and_get_function_pointer #3676

Closed
nxtn opened this issue Jul 9, 2019 · 6 comments
Closed

Using load_assembly_and_get_function_pointer #3676

nxtn opened this issue Jul 9, 2019 · 6 comments
Labels
area-Host question Answer questions and provide assistance, not an issue with source code or documentation.
Milestone

Comments

@nxtn
Copy link
Contributor

nxtn commented Jul 9, 2019

Why is the new API different from the coreclr_create_delegate, requiring a delegate type for every different method signature?

If I have a lot of methods to call, is it recommended to define delegate types or create ComponentEntryPoint wrappers for them?

@jeffschwMSFT
Copy link
Member

cc @vitek-karas @elinor-fung

@nxtn
Copy link
Contributor Author

nxtn commented Jul 9, 2019

dotnet/coreclr#23958 may answer the first question.

If you are not going to "expose the full set of functionality to the connecting coreclr/native host dll", can I get the CoreCLR host from nethost - hostfxr - hostpolicy layers and directly call coreclr_create_delegate instead of using this heavyweight API?

@jeffschwMSFT
Copy link
Member

can I get the CoreCLR host from nethost - hostfxr - hostpolicy and directly call coreclr_create_delegate instead of using this heavyweight API?

Yes. The nethost layer offers a few convience apis to assist with 1) locating the correct .NET Core version to load, and 2) generates the necessary initialization parameters using the standard logic. Once .NET Core (eg. coreclr) is loaded, you can then use the exports as you would before. The hope is that value comes in finding and initializing.

The current nethost is a first step on a journey to enable a richer hosting experience. We did not want to lead with too much, as more comes on line.

@vitek-karas
Copy link
Member

The load_assembly_and_get_function_pointer is not meant as a replacement for a low level so called "embedding" API - which would let you work with managed objects/methods from native code in a generic manner. It is meant to provide a robust way to initialize the runtime and get a way to call into managed code.

We expect people to use this functionality to either make a single (or few) calls to managed code, or to build their own "interop" on top. The problem with allowing to create a native function pointer to any method is that if the method's signature is not super simple, there's no way to customize the marshaling. For example if the method would take a string argument, there would be no way to specify which encoding should be exposed to the native code... and so on.

The "embedding API" which would allow native code to have much greater control over the communication with managed is something we are considering for the future.

We did consider exposing the coreclr hosting directly (from the new functionality), but it creates some non-trivial problems with lifetime management. And also going forward it would be really tricky to do this in a consistent way if the runtime is actually Mono.

@nxtn
Copy link
Contributor Author

nxtn commented Jul 9, 2019

Thanks a lot for your answers. I would be super happy to see the "embedding APIs" in the future.

there's no way to customize the marshaling

We used MarshalAsAttribute and StructLayoutAttribute.CharSet to specify the marshaling behaviors in reverse P/Invoke.

@vitek-karas
Copy link
Member

Sorry - completely missed your reply (for a long time apparently).
With the API, you specify the delegate which can (And should) contain the marshalling attributes, basically the way you describe it. I'm not sure if this would work if the same attributes were present on the method itself (it might).

There's a slight benefit to the current approach and that is it doesn't require us to create a new type (the delegate type) on the fly. So less "magic". I understand that it can be cumbersome if you want to use it on many public APIs.

As noted above, if the use case is to call many managed methods from native, we think the better way to do that is to use the existing hostfxr functionality to get a single "helper" in managed, though which you would expose all the managed methods (basically as simple reverse PInvokes). This lets us keep the existing native APIs relatively simple and also provides lot more flexibility to the exact implementation of this pattern. Not counting the performance benefits (the existing functionality has to perform non-trivial amount of checks to and cache lookups and finally a reflection call (creation of the delegate) to even get to the managed code, direct reverse PInvoke is much faster as it can avoid all of that).

If you have additional questions or issues with this, please open a new issue (preferably in dotnet/runtime repo).

@msftgits msftgits transferred this issue from dotnet/core-setup Jan 30, 2020
@msftgits msftgits added this to the Future milestone Jan 30, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Host question Answer questions and provide assistance, not an issue with source code or documentation.
Projects
None yet
Development

No branches or pull requests

4 participants