-
Notifications
You must be signed in to change notification settings - Fork 120
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
MapViewOfFile should generate an overload returning SafeMemoryMappedViewHandle #561
Comments
We generate SafeHandles where a typedef struct with a release attribute is applied. This would have to come from the metadata. |
What exactly do you want to see MapViewOfFile return instead of void *? |
@mikebattista I would expect it to return |
That's how it would be projected, but I'm asking about the metadata. |
@AArnott would need to answer that part. I'm not sure how the metadata relates to the CsWin32 project, and I'm only aware of the output from the latter. |
For example, CreateFile returns the below in the metadata which C#/Win32 translates into a .NET SafeHandle. Other projections handle it differently.
@AArnott sounded like you wanted something similar here but could you clarify what definition you expect? |
Apparently the value returned from this method is supposed to be released with |
So something like this?
|
Yes, that looks good. |
Somewhat related, the Zig projection would be able to make use of some way of knowing which types are "handles" and which aren't. Reason being is that Zig distinguishes between handles that are "optional", allowing |
Seems ok. #423 (comment) |
FWIW CsWin32 figures out which structs are handle by convention, and a tiny hard-coded list of one: https://github.com/microsoft/CsWin32/blob/14443c08be185c26d91da5acac8c6acaccd37622/src/Microsoft.Windows.CsWin32/Generator.cs#L3114-L3132 |
There are several MapViewOfFile APIs. We need clarity on which Unmap function should be used for each and what to do about additional flags if anything.
Available Unmap functions:
|
AFAICT, you can use any Unmap function with any Map function, but if you used a Map function that takes process handle parameter and specified a process other than the caller, then you must use UnmapViewOfFile2 so that you can specify the same process (although not necessarily the same process handle). |
Thanks, @KalleOlaviNiemitalo. |
If we return a |
That's an interesting idea, as it retains more discoverable types than IntPtr would. |
Yes we could update |
Re-opening this issue as I don't think From the docs:
|
Looking at the .NET code in the original post, it appears this is not a real handle, is just a handle by name, and is just a RAII wrapper around the returned So proposed actions include:
|
We can keep the autotype but change it to |
@kennykerr Can you double-check me here? Believe this change will resolve microsoft/windows-rs#2436 |
Ideally, there would be a distinct attribute for these "invented" handle types, like |
I see we still have |
The following APIs deal with pointers, not handles
.NET
So to remain language neutral, I argue the aforementioned APIs should return a void*/IntPtr/etc. type. I'm not opposed to additional metadata that would assist others in generating RAII wrappers (e.g. RAIIFree). (I recognize that work is not yet complete though.) |
We have many cases like this where we add a typedef that is returned by one API and passed to another. Unless you're saying these APIs are unlike all the others where we have void* typedefs, I'm unclear on the problem. |
Yes, these are unlike functions that return handles. These functions return addresses, just like say |
I'm fine reverting the changes for now but that leaves the original feedback unaddressed. |
Is something like this possible? Source: WINBASEAPI
...
LPVOID
WINAPI
MapViewOfFile(
_In_ HANDLE hFileMappingObject,
_In_ DWORD dwDesiredAccess,
_In_ DWORD dwFileOffsetHigh,
_In_ DWORD dwFileOffsetLow,
_In_ SIZE_T dwNumberOfBytesToMap
); Target: /* ... */
[return: RAIIFree("UnmapViewOfFile")]
public static extern void* MapViewOfFile(
[In] HANDLE hFileMappingObject,
[In] FILE_MAP dwDesiredAccess,
[In] uint dwFileOffsetHigh,
[In] uint dwFileOffsetLow,
[In] UIntPtr dwNumberOfBytesToMap
); Folks can then choose to do something with the RAIIFree attribute if needed. |
Or if you want/need to create a type, at least drop the handle suffix, e.g. |
Was it the HANDLE suffix that was the problem? Or the fact that there was a NativeTypeDef at all? What you're suggesting is how we use typedefs in many places but everyone said that was problematic here. |
Yeah the HANDLE suffix was bugging me since the API doesn't deal with handles and restarted handle provenance discussion in the Rust community 😂 There's a separate discussion to be had about NativeTypeDefs and whatnot, but am okay to punt that. |
So if we add back a void* NativeTypeDef but remove the HANDLE suffix, that works for everybody? |
I suggested Ideally the resolution to #1533 would guide the fix here. |
Let me know if anything looks wrong. Below is the
|
That looks okay to me. Am wondering if we can go an extra step and return the APIs to their roots to keep the core definitions separate from metadata sugar. Maybe something like:
I think we have a similar issue already being tracked, will poke around. |
I took the |
That shouldn't generally be true. In the MapViewOfFile case, you should unwrap the struct to the native type within. CreateCompatibleDC is interesting because it returns a MetadataTypedef (CreatedHDC) that is AlsoUsableFor a NativeTypedef (HDC) and you'd want the function to return the NativeTypedef. Is this an outlier? Or did you run into other examples of this case? |
I'm happy to do that but then I need the native type within |
Since the metadata drops the original type information, I have no way to determine how widespread this problem is. |
CreatedHDC does appear to be an outlier here. Ideally CreateCompatibleDC would just return HDC, but CreatedHDC was created to allow for a different RAIIFree function (DeleteDC). Given that HDCs need to be closed with different functions depending on the API, I'm wondering if we should just return HDC here and remove RAIIFree and leave it up to the caller to call the proper API for the scenario. This is the same reason we left off RAIIFree on the MapViewOfFile typedef since it depends on the scenario. |
That sounds good to me - I was never able to get |
Will do.
For that, please take a look at #389 (comment) and let me know what you think. |
I won't be using |
That's not true. In the latest builds, HINSTANCE and HMODULE both exist and are interchangeable. That relationship is defined by AlsoUsableFor. You're going to have problems if you don't support this. |
That's only because the metadata has two types for the same thing. If that's all it's for, you should probably consider calling it a "type alias" so that they're interchangeable rather than having two distinct types that now have to point at each other and have languages have to track down all uses of one or the other and allow then to be used interchangeably. That's just way too contrived in practice. Just have one type say |
They're both NativeTypedefs that exist in the headers. AlsoUsableFor means support implicit conversion between the types. C# can handle this just fine. I'm assuming Rust can as well. |
Actual behavior
MapViewOfFile
only generates an overload returningvoid*
.Expected behavior
A separate overload, e.g. a generated
MapViewOfFile_SafeHandle
method, should returnSafeMemoryMappedViewHandle
.https://github.com/dotnet/runtime/blob/57bfe474518ab5b7cfe6bf7424a79ce3af9d6657/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.MapViewOfFile.cs#L12-L18
https://referencesource.microsoft.com/#System.Core/Microsoft/Win32/SafeHandles/SafeMemoryMappedViewHandle.cs,fbe85260617a73ea
Repro steps
NativeMethods.txt
content:NativeMethods.json
content (if present):N/A
Context
0.1.506-beta
LangVersion
(if explicitly set by project):9
The text was updated successfully, but these errors were encountered: