Replies: 3 comments 6 replies
-
I'm confused. A ref is essentially a pointer, just one tracked by the garbage collector. So you effectively have a pointer to a pointer, and you change that to a pointer to a native-integer by pinning the pointer variable? I've written tons of unsafe code and I've never had the need to do what you're suggesting. |
Beta Was this translation helpful? Give feedback.
-
I personally have a helper in IL to do this for this exact usage (except mine is based on Another option these days (.NET 9+ (for .NET 7/8, you can just replace the BitCast with some pointer tricks)) would be: ref struct PtrRef<T>(ref T* reference)
{
public ref T* reference = ref reference;
}
ref struct NIntRef
{
public ref nint reference;
}
return ref Unsafe.BitCast<PtrRef<T>, NIntRef>(new(ref reference)).reference; which can be fully written from C#, but relies on UB (in particular, assuming that the layouts are going to be what you'd expect, etc.), but I think it's fine for now with the current runtimes/GCs (I wouldn't really recommend this solution due to the UB, but it is probably practically fine for now, and you could replace it with an IL implementation later, so it's future proof in the sense that you can always fix it later if you need to). Note that your API was proposed previously here. |
Beta Was this translation helpful? Give feedback.
-
I ran into this exact same problem awhile ago, and I created a nuget package for it: https://github.com/rickbrew/PointerToolkit So you could use that for now if you'd like until/if we get something built-in to the runtime. @hamarb123 's solution might be simpler though, my package predates things like int value = ...;
int* pValue = &value;
ref int* refpValue = ref pValue;
ref nint refAsNint = ref UnsafePtr.As<int, nint>(ref refpValue); |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Currently as far as I know, there is no way to convert from a
ref T*
to aref nint
. This can be an important operation if you want to do atomic operations or volatile reads/writes on aref T*
, because the methods inInterlocked
andVolatile
expected aref nint
.This conversion can be done like this:
However this is not non-obvious and feels kinda hacky. I think there should be a method like this build into the runtime. I do not know where this method should go (maybe
Unsafe
?) or what it should be called, hence I have not made a proper API proposal.Beta Was this translation helpful? Give feedback.
All reactions