为了账号安全,请及时绑定邮箱和手机立即绑定

Unsafe.AsPointer<T>(ref T value) 如何工作?

Unsafe.AsPointer<T>(ref T value) 如何工作?

C#
收到一只叮咚 2021-11-07 18:43:42
在 C# 中,您不能创建指向托管类型的指针,但使用此 API,您可以使用Unsafe.AsPointer<T>.https://www.nuget.org/packages/System.Runtime.CompilerServices.Unsafe/我看到使用 ILSpy 的源代码,我看到了这个:[MethodImpl(MethodImplOptions.AggressiveInlining)][System.Runtime.Versioning.NonVersionable]public unsafe static void* AsPointer<T>(ref T value){    return &value;}同样在其他类似的 API 中://Unity.Collections.LowLevel.Unsafe.UnsafeUtilitypublic unsafe static T ReadArrayElement<T>(void* source, int index){    return *(T*)((byte*)source + index * sizeof(T));}这是如何工作的以及如何复制这种行为?
查看完整描述

1 回答

?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

有问题的代码不是有效的 C# 代码,而且最初可能不是用 C# 编写的。您看到的是 ILSpy 的底层代码的 C# 表示 - C# 语法能够表示这一点,因为它只是一个编译器规则,表明您无法获得指向托管类型的指针。


我的猜测(我不知道这个事实)有问题的代码首先是用 IL 编写的——如果你将它反编译为 IL,你可以看到它是微不足道的:


.method public hidebysig static 

    void* AsPointer<T> (

        !!T& 'value'

    ) cil managed flag(0100) 

{

    .custom instance void 

        System.Runtime.Versioning.NonVersionableAttribute::.ctor() = (

        01 00 00 00

    )

    // Method begins at RVA 0x2190

    // Code size 3 (0x3)

    .maxstack 1


    IL_0000: ldarg.0

    IL_0001: conv.u

    IL_0002: ret

} // end of method Unsafe::AsPointer

(这是来自 System.Runtime.CompilerServices.Unsafe.dll。)


托管实例被加载到堆栈上,然后它只是作为无符号指针值返回。


如果您想重新创建此行为,您可以 - 只需在 IL 中编写您的 DLL 并编译它,然后从支持指针的任何其他 .NET 语言中引用它。


查看完整回答
反对 回复 2021-11-07
  • 1 回答
  • 0 关注
  • 320 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信