kaalus
kaalus

Reputation: 4574

Is it possible to get a pointer to a boxed unmanaged value type?

Is it possible to get a pointer to a boxed unmanaged value type, without writing a large switch statement that does a cast for every supported type? Something like:

object val;         // Contains a boxed unmanaged value, such as int, long, byte, etc.
void* ptr = &val;   // Obviously does not compile
DoStuffWithPointer(ptr);

instead of

object val;   // Contains a boxed unmanaged value, such as int, long, byte etc.
if (val.GetType() == typeof(byte)) 
{
    var typedValue = (byte)value;
    DoStuffWithPointer(&typedValue);
}
else if (val.GetType() == typeof(short)) 
{
    var typedValue = (short)value;
    DoStuffWithPointer(&typedValue);
}
else 
    // ... and so on

Btw. I know the pointer points to a local variable on the stack, and will become invalid once the function returns. That's fine.

Upvotes: 0

Views: 430

Answers (1)

OwnageIsMagic
OwnageIsMagic

Reputation: 2309

You can use ref T Unsafe.Unbox<T>(object) to get managed pointer (ref T) to the boxed value. Getting unmanaged pointer (void*/IntPtr) to boxed value is really a race with GC, unless you have pinned the box with GCHandle, so you can use
IntPtr GCHandle.AddrOfPinnedObject()
(or shoot yourself into the leg via T* Unsafe.AsPointer<T>(ref T)).

(!) Read carefully Remarks section on Unsafe.Unbox: You are not allowed to directly mutate contained value (you can only call properties/methods on it), use StrongBox<T> / OneOf<T1, T2, ...> like classes, if you need to change the value.


Btw. I know the pointer points to a local variable on the stack, and will become invalid once the function returns. That's fine.

Seems like you are ok with coping value from box to stack, then you can just use concise switch syntax:

switch (val)
{
    case int  typedValue: DoStuffWithPointer(&typedValue); break;
    case byte typedValue: DoStuffWithPointer(&typedValue); break;
    // ...
}

Upvotes: 3

Related Questions