-
Notifications
You must be signed in to change notification settings - Fork 94
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
Enable friendly overload generation for optional ref
, out
and in
parameters
#137
Comments
ref
or out
parametersref
, out
and in
parameters
I am trying to use this package and I ended up exactly in this situation: either I mark most of my code |
We should keep #1040 in mind. As an implementation for such a method, getting a |
Sorry guys for the stupid question, but I have not yet understood what is the recommended way to handle such situations. As soon as I'm getting into CsWin32 I had to face the same issues stated from #137 (comment), even for simple functions that just return What would be the recommended workaround for this and all the other similar signatures? |
@netcorefan1 You can isolate the using System.Runtime.CompilerServices;
using Windows.Win32;
using Windows.Win32.Foundation;
HWND hwnd = default; // set to value out of scope for sample
PInvoke.GetWindowThreadProcessId(hwnd, out uint processId);
// Ways of providing null in the optional out parameter.
PInvoke.GetWindowThreadProcessId(hwnd, out Unsafe.NullRef<uint>());
PInvoke.GetWindowThreadProcessId(hwnd);
namespace Windows.Win32
{
partial class PInvoke
{
internal unsafe static uint GetWindowThreadProcessId(HWND hwnd)
{
return GetWindowThreadProcessId(hwnd, null);
}
internal unsafe static uint GetWindowThreadProcessId(HWND hwnd, out uint lpdwProcessId)
{
fixed (uint* _lpdwProcessId = &lpdwProcessId)
return GetWindowThreadProcessId(hwnd, _lpdwProcessId);
}
}
} |
In my own experiments I started to generate the base functions with in/ref/out (not pointers) and manually write overloads passing Unsafe.NullRef - thats a little less manual work than having to write all the overloads. I reserve generating pointer arguments only for cases where multiple items are being passed (and then write overloads using spans and leave out length parameters). Just reporting from what worked for my own experiments, not necessarily the best for this project, but figured I'd mention it. |
Note to self: #1081 reveals that while this may work for |
That makes sense, I've stopped using classic COM interop on .NET Core, since I'm already generating custom code anyways I can go the full way and use the new interop features of .NET 7+ Though if this effort is out of scope for this project this might mean you'll have to wait for the COM source generators to become more mature and feature complete compared to classic COM interop, right now its a bit rough to use the builtin generators (e.g. property syntax isn't supported, Variant marshalling is missing, etc.) I assume API compatibility with Desktop Framework is no concern because Unsafe.NullRef doesn't work there anyways. Any project where I need Desktop Framework compatibility I try to generate things in a way that are source-compatible via extension methods or implicit conversions, but not binary compatible. Allows me to write code usable for both frameworks, but not having to make compromises or miss any of the new features when writing new code that doesn't need to run on Desktop Framework. |
Sure it does. |
uh, what? the doc page says its available in .NET 5-8, and it certainly isn't available in a fresh project multitargeting net472/net8. If I try to import the System.Runtime nuget package the newest version compatible with both is 4.3.1; is there a compatibility nuget package I'm missing? also I was under the impression that ref-returns needed runtime changes when they were introduce so they don't work in Desktop Framework (but I just heared that and haven't tried to verify it myself) |
apisof.net is more reliable in my experience than docs.microsoft.com. apisof.net tells you that Unsafe.NullRef is available on net472 via the System.Runtime.CompilerServices.Unsafe package, which is available as low as net461. As for ref-returns, that's off topic for this thread. But as that's a language feature, I expect the C# compiler will only permit its use when targeting the runtimes that support it. It's pretty good at that. |
We should use
ref
orout
modifiers to avoid pointers in more places. We don't do it today where the argument is optional, because C# disallowsnull
forref
orout
parameters.However, callers can use
Unsafe.NullRef<T>
. We could even add this tip to the API docs so folks can discover it.And the helper function can use
Unsafe
'sSkipInit
andIsNullRef
methods to detect when this has occurred, if this were ever necessary.The text was updated successfully, but these errors were encountered: