-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
[NativeAOT] Decorating functions with UnmanagedCallersOnlyAttribute does not export them for executables #78663
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. |
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas Issue DetailsIntroductionNativeAOT conveniently enables Class Library projects to export native symbols in the export table of the PE, typically functions, which is an excellent asset for interoperability with unmanaged software. In native applications (e.g., written in C/C++), using the directive Currently, when decorating a function with the attribute MotivationI'm looking forward to similarly exporting functions in the export table of my managed applications (.exe) for interoperability reasons. Furthermore, I would expect the compiler to honor the attribute Bug reportVersion Used: Retail .NET SDK 7.0.100 with Visual Studio 17.4.0 Steps to Reproduce:
[UnmanagedCallersOnly(EntryPoint = "FancyName2")]
public static int FancyName2(int a, int b)
{
return a + b;
}
Expected Behavior: The export table of the PE format shows the Actual Behavior The function Additional detailsInspecting a running application compiled using NativeAOT, I could notice various symbols present in the memory of the process. As an example, the picture below highlights a static function called Creating a thread at this address properly invokes the managed function. Hence, I think tagging this location in the export table using the same logic as for managed libraries should be doable.
|
Seems reasonable, but a little niche. Would take a PR if there were one ready. |
I agree that this is niche. You can work around this by passing the .def file with the list of entrypoints to the linker yourself. I expect that most uses of |
I think the request is to only expose those that specify the @JamesMenetrey you can already do this today if you add:
To a PropertyGroup in your project file. It's a bit of a backhanded way to exploit the way things are set up in the targets. The actual product change to fix this in a more supportable way would be a change to the targets in https://github.com/dotnet/runtime/tree/main/src/coreclr/nativeaot/BuildIntegration. |
Consider statically linking some extra C code into the exe and calling between C# and C in both directions. |
Functions decorated with the attribute UnmanagedCallersOnlyAttribute are not inserted in the export table of the compiled file when the .NET project is an executable (i.e., as opposed to a library). This change removes the difference between a library and an executable regarding the handling of the attribute UnmanagedCallersOnlyAttribute. As such, decorated functions with this attribute are now adequately exported for libraries and executables. Fix dotnet#78663
Dear all, First, thanks for your detailed input and insight that allowed me to understand the underlying mechanism works better. @MichalStrehovsky Many thanks for pointing me to a working workaround. Adding this line in the project file correctly exports the symbols as annotated with I have reviewed the many files in the link you provided to me and created a PR fixing the issue (#78738). After further testing with both a .NET library and two .NET executables (a console and Windows Forms application), I noticed that decorating a function with Filling the property Could you please review my PR (#78738) and provide feedback if this change is sound? Thanks! |
Introduction
NativeAOT conveniently enables Class Library projects to export native symbols in the export table of the PE, typically functions, which is an excellent asset for interoperability with unmanaged software.
In native applications (e.g., written in C/C++), using the directive
extern __declspec(dllexport)
similarly creates an entry in the export table for the given function. This capability works for both unmanaged libraries (.dll) and unmanaged executables (.exe).Currently, when decorating a function with the attribute
UnmanagedCallersOnlyAttrribute
does not insert a symbol in the export table when the managed project is an application (.exe). Copy/paste the definition of the same function in a project of type Class Library works.Motivation
I'm looking forward to similarly exporting functions in the export table of my managed applications (.exe) for interoperability reasons.
Admittedly, the use case of exporting functions for executables is small compared to libraries. Nonetheless, I find this is a valuable capability on my end, where I mainly work on low-level forms of interoperability (i.e., creating threads in other processes for code execution).
Furthermore, I would expect the compiler to honor the attribute
UnmanagedCallersOnlyAttribute
for exporting the function in the export table since both libraries (.dll) and executables (.exe) use the PE file format, which enables the export of symbol of functions.Bug report
Version Used: Retail .NET SDK 7.0.100 with Visual Studio 17.4.0
Steps to Reproduce:
win-x64
using NativeAOT.Expected Behavior:
The export table of the PE format shows the
FancyName2
function.Actual Behavior
The function
FancyName2
is not present. Note that performing the same operation for a project of type Class Library correctly exports the function.Additional details
Inspecting a running application compiled using NativeAOT, I could notice various symbols present in the memory of the process. As an example, the picture below highlights a static function called
FancyName2
in the classProgram
, from a Windows Forms application.Creating a thread at this address properly invokes the managed function. Hence, I think tagging this location in the export table using the same logic as for managed libraries should be doable.
The text was updated successfully, but these errors were encountered: