- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有代码使用指针对数据 block 进行异或,速度很快,但我想摆脱对程序集的“不安全”要求。如果我将其更改为使用 LayoutKind.Explicit 并将“ulong[]”覆盖在“byte[]”之上,我基本上在做与指针相同的事情,但它似乎同样危险。这两者之间的主要区别在于“安全”版本的速度大约是“不安全”版本的 1/2。
这是绕过“不安全”程序集的合法方法,还是一次访问 byte[] 1 个字节是安全执行此操作的唯一合法方法?
private unsafe static void UnsafeEncode(
byte[] buffer, int bufPos, ulong[] vector, int SectionLength, byte vectorIndex)
{
fixed (byte* p = &buffer[bufPos])
{
ulong* pCur = (ulong*)p;
ulong* pEnd = pCur + SectionLength;
while (pCur < pEnd)
{
*pCur ^= vector[vectorIndex++];
pCur++;
}
}
}
[StructLayout(LayoutKind.Explicit)]
private struct ArrayOverlay
{
[FieldOffset(0)]
public byte[] Bytes;
[FieldOffset(0)]
public ulong[] Longs;
}
private static void SafeEncode(
byte[] buffer, int bufPos, ulong[] vector, int SectionLength, byte vectorIndex)
{
var overlay = new ArrayOverlay { Bytes = buffer };
int shiftleft = (bufPos & 7) << 3;
int pos = bufPos >> 3;
if (shiftleft == 0)
{
for (int i = 0; i < SectionLength; i++)
overlay.Longs[i + pos] ^= vector[vectorIndex++];
}
else
{
int shiftright = (64 - shiftleft) & 63;
ulong oldVec = 0;
for (int i = 0; i < SectionLength; i++)
{
var vec = vector[vectorIndex++];
overlay.Longs[i + pos] ^= (vec << shiftleft) | (oldVec >> shiftright);
oldVec = vec;
}
overlay.Longs[SectionLength + pos] ^= (oldVec >> shiftright);
}
}
最佳答案
Is this a legitimate way to get around having an "unsafe" assembly, or is accessing the byte[] 1 byte at a time the only legitimate way to do this in a safe manner?
这是合法的,因为它 1) 有效,并且 2) 可以产生正确的结果。
诚然,它不一定“安全”,因为您可以通过这样做来做“讨厌”的事情,但它仍然会起作用。在这种情况下,您肯定违反了安全代码的精神,因为您可以做“安全”代码中不允许的事情,例如有效地绕过数组长度检查并导致缓冲区溢出。
一次访问数组一个元素更符合“安全”代码的精神,但有时使用这样的技巧很有值(value),因为它提供了一种需要时的性能机制.如果您的特定场景需要性能,并且正常机制无法充分执行,这可能是一种使代码“工作”的方法,因为它满足您的规范(性能要求),而不会违反标记一个安全约束装配不安全。
关于c# - 使用 LayoutKind.Explicit 绕过 "unsafe"指针是否合法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16967146/
运行这段代码时: using System; using System.Collections.Generic; using System.Linq; using System.Text; using
我有一个结构,其中有一个报告为重叠的非重叠字段。 [FieldOffset(8)] Int32 X; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1
问题 我尝试使用 [StructLayout(LayoutKind.Explicit)] 构建一个结构 (SA),它有一个字段是另一个 struct (SB). 首先:我很惊讶我被允许在没有[Stru
我有代码使用指针对数据 block 进行异或,速度很快,但我想摆脱对程序集的“不安全”要求。如果我将其更改为使用 LayoutKind.Explicit 并将“ulong[]”覆盖在“byte[]”之
我需要以关于声明顺序的保证顺序获取字段信息。现在我正在使用属性来指定顺序。 有没有更自动化的方法来做到这一点? 有没有人知道 LayoutKind.Sequential 是如何工作的,我是否可以应用它
我正在尝试创建一个 F# 等价的标记联合。我需要在应用程序代码的热路径中使用它,其中有区别的联合可能会导致过多的堆分配。 这是示例: [] type Result = [] val m
首先,据说 boolean 类型具有四字节值的默认编码类型。所以下面的代码有效: struct A { public bool bValue1; pub
如果结构包含 DateTime 字段,为什么 LayoutKind.Sequential 的工作方式不同? 考虑以下代码(必须在启用“不安全”的情况下编译的控制台应用程序): using System
默认情况下,C# 中的 structs 是使用 [StructLayout( LayoutKind.Sequential )] 实现的,原因基本上表明这些类型的对象通常用于 COM Interop 及
下面是一个完整的程序。只要您不取消注释顶部的“#define BROKEN”,它就可以正常工作。中断是由于 PInvoke 未能正确编码联合。所讨论的 INPUT_RECORD 结构有许多子结构,可以
我有一个传输二进制数据的设备。为了解释数据,我定义了一个匹配数据格式的 struct。 struct 有一个 StuctLayoutAttribute与 LayoutKind.Sequential .
我想在非托管 PInvoke 方案中使用 System.Numerics.Complex。使用 ILSpy,我注意到它没有分配 LayoutKind.Sequential 属性。 /// Repres
我是一名优秀的程序员,十分优秀!