嗯,有一些明显的区别:
固定缓冲区:
-unsafeswitch 进行编译)。使用MarshalAs属性:
但我找不到答案,为什么首先需要固定缓冲区?
什么时候必须使用它们?
假设可以验证常规托管数组的大小,为什么要使用它?
我可以想到性能限制,这可能会让人们选择固定缓冲区而不是常规数组......
仅此而已吗?
提前致谢。
是的,效率当然是首要原因。当您应用时,必须始终UnmanagedType.ByValArray对结构进行编组。换句话说,由于结构的非托管布局不同,CLR 被迫创建该结构的新副本并使用托管结构中的值对其进行初始化。当您使用固定缓冲区时,可以避免这种情况,前提是结构体的其他成员也可以进行 blittable。在这种情况下,CLR 可以简单地传递一个指向该结构的指针。当然更快。
在一些互操作场景中,您必须使用固定大小的缓冲区。通常,当数组成员未对齐时,就会违反 .NET 内存模型的原子性保证。或者,您声明一个联合(字段相互重叠)和 CLR 对象,以防止引用类型的字段与值类型的字段重叠。这与垃圾收集器不兼容,它无法可靠地检测对象指针。在这种情况下,您将在运行时收到 TypeLoadException。
这两种情况基本上都是无法验证的。如果本机代码写回结构体总是不安全的,当它写入超过数组末尾时会发生内存损坏。极难诊断。使用固定大小缓冲区时需要显式使用unsafe关键字仅适用于在 C# 代码中访问固定大小缓冲区时缺少索引检查。
| 归档时间: |
|
| 查看次数: |
429 次 |
| 最近记录: |