You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否无需编写大型switch语句获取装箱非托管值类型的指针?

获取装箱非托管值类型指针的无switch方案

当然可以不用编写大型switch语句实现需求,下面提供两种高效实现方式,均需项目启用不安全代码(在项目设置中开启"允许不安全代码"选项):

方案1:直接获取堆上装箱值的指针

该方法无需拆箱复制,直接指向堆中装箱值的内存区域,只要对象未被GC回收,指针就有效:

using System.Runtime.CompilerServices;

object val = 123L; // 示例:装箱的long类型

void* GetBoxedHeapPointer(object boxedValue)
{
    // 获取装箱对象的原始指针
    IntPtr objBasePtr = Unsafe.As<object, IntPtr>(ref boxedValue);
    // 偏移对象头(同步块索引 + 方法表指针),定位到值的起始地址
    return (void*)(objBasePtr + IntPtr.Size * 2);
}

// 使用示例
void* ptr = GetBoxedHeapPointer(val);
DoStuffWithPointer(ptr);

方案2:获取栈上值的指针(与原switch逻辑行为一致)

如果你需要和原代码一样,指针指向栈上的局部变量(接受函数返回后指针失效的情况),可以通过动态分配栈内存并复制装箱值实现:

using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

object val = (byte)0xAB; // 示例:装箱的byte类型

void* GetBoxedStackPointer(object boxedValue)
{
    Type valueType = boxedValue.GetType();
    int valueSize = Marshal.SizeOf(valueType);
    
    // 在栈上分配对应大小的内存缓冲区
    void* stackBuffer = Unsafe.AllocateStack(valueSize);
    // 获取堆上装箱值的指针
    void* heapValuePtr = GetBoxedHeapPointer(boxedValue);
    // 将堆上的值复制到栈缓冲区
    Unsafe.Copy(stackBuffer, heapValuePtr, (uint)valueSize);
    
    return stackBuffer;
}

// 使用示例
void* ptr = GetBoxedStackPointer(val);
DoStuffWithPointer(ptr);

注意事项

  • 两种方法均依赖System.Runtime.CompilerServices.Unsafe类,.NET Core 2.0+/.NET 5+默认包含该类。
  • 方案1的指针依赖装箱对象的生命周期,若对象被GC回收,指针会失效;方案2的指针仅在当前栈帧有效,函数返回后即失效,符合你的预期。

内容的提问来源于stack exchange,提问作者kaalus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 11:50:21