是否可以获取指向装箱非托管值类型的指针?

问题描述 投票:0回答:1

是否可以获取指向装箱非托管值类型的指针,而无需编写大型 switch 语句来对每个受支持的类型进行强制转换?比如:

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

而不是

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

顺便说一句。我知道该指针指向堆栈上的局部变量,一旦函数返回,该指针就会失效。没关系。

c# pointers boxing
1个回答
2
投票

您可以使用

ref T Unsafe.Unbox<T>(object)
来获取指向装箱值的 托管指针 (
ref T
)。 将非托管指针 (
T*
) 获取到装箱值确实与 GC 竞争,除非您已使用
GCHandle
固定了该框,并且可以使用
T* Unsafe.AsPointer<T>(ref T)
来完成。

(!) 仔细阅读Unsafe.Unbox上的

备注
部分:不允许直接改变包含的值(只能调用其属性/方法),如果需要,请像类一样使用
StrongBox<T>
更改值。


顺便说一句。我知道该指针指向堆栈上的局部变量,一旦函数返回,该指针就会失效。没关系。

看来您可以将值从框复制到堆栈,那么您可以使用简洁的 switch 语法

    switch (val)
    {
        case int typedValue: DoStuffWithPointer(&typedValue); break;
        case byte typedValue: DoStuffWithPointer(&typedValue); break;
        //...
    }
© www.soinside.com 2019 - 2024. All rights reserved.