-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
A module initializer will not be triggered when accessing a forwarded type #77632
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Module initializers are not triggered by referencing a type. They are only triggered by accessing a method or a static field. This is documented in https://github.com/dotnet/runtime/blob/main/docs/design/specs/Ecma-335-Augments.md#module-initializer |
I see. I suppose the workarounds I listed are probably the only options currently available then? |
The solutions that we use in dotnet/runtime in these situations are either:
I would not recommend the embedded resource trick. It is not compatible with trimming and AOT. |
I had originally attempted the first approach, though due to the library needing to target The second approach would unfortunately be a huge amount of code and complexity for this case, especially since these types are supposed to be publicly exposed. The trimming and AOT concerns are good points, I had only intended to use this trick in JIT scenarios but being unable to trim is still not ideal. |
This is a problem I encountered while investigating mitigations for #60573.
Imagine that we have
Library
, which contains a number of structures for interop. However, the native structures have differing packing for certain platforms.To work around this, I split the project up as follows:
Library
Library.Platform.Windows
andLibrary.Platform.Unix
as embedded resources.AppDomain.Current.AssemblyResolve
to load the appropriate platform assembly.Library.Platform
.Library.Platform
Library
to compile against.Library
.Library.Ref
Library
andLibrary.Platform
combined.AssemblyName
is set toLibrary
.Library.Platform.Windows
Library.Platform
, but compiled with theWINDOWS
define active.AssemblyName
is set toLibrary.Platform
.Library.Platform.Unix
Library.Platform
, but compiled with theUNIX
define active.AssemblyName
is set toLibrary.Platform
.A program would then compile against
Library.Ref
, but loadLibrary
. However, whenever an attempt is made to access one of the types, the program will throw aFileNotFoundException
forLibrary.Platform
due to the module initializer not being called when accessing forwarded types.Is there any way to ensure that the module initializer is invoked in this situation without manual intervention from the API consumer? Or would it be possible to change the behaviour of module initializers to also run for forwarded types?
Workarounds
This can be worked around by exposing an empty
static
method onLibrary
that consumers are required to call before accessing anything else, but this is certainly not an ideal solution.I've also considered writing a C# source generator that emits the following into a consuming project:
But naturally this would only work for C#.
The text was updated successfully, but these errors were encountered: