在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.UnsafeUtility
public unsafe static T ReadArrayElement<T>(void* source, int index)
{
return *(T*)((byte*)source + index * sizeof(T));
}
它是如何工作的以及如何复制这种行为?
最佳答案
有问题的代码不是有效的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语言中引用它。
关于c# - Unsafe.AsPointer <T>(引用T值)如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51599375/