2014-09-04 104 views
0

根据http://referencesource.microsoft.com/#mscorlib/system/runtime/interopservices/safebuffer.cs为什么使用Marshal.AlignedSizeOfStruct <T>代替SafeBuffer.WriteArray中的Marshal.SizeOfStruct <T><T>和SafeBuffer.ReadArray <T>?

SafeBuffer使用结构类型的对齐大小而不是结构类型的实际大小。看起来这会在编写需要密集打包的结构数组时以及从缓冲区中先前存在的密集打包的非结构数组结构读取时导致对齐问题。在第一种情况下,使用对齐而不是实际大小会导致不需要的填充字节。第二,数据被破坏。我有两个问题(4真的,但3都跟):

  1. 有没有解决这个其他的方式比手动校准使用顺序调用访问SafeBuffer.Write<T>/Read<T>(这是比较慢),或开沟SafeBuffer类(因此完全不错UnmanagedMemoryAccessor类)?
  2. 这种选择背后的原因是什么?为什么CLR在非托管内存上强制执行它自己的对齐要求?为什么这不被视为一个错误?

回答

1

Hmya,对这些问题的回答总是主观的,我们没有.NET Framework设计师在这里贡献他们的设计会议笔记给我们。但你可以放心地假设这是而不是一个错误,这是一个很大的痛苦。毫无疑问,在.NET中支持MMF需要这么长时间的原因至少有一个。

每个人都喜欢忽略或希望结构包装和对齐的细节。 CLR在隐藏它们方面做了非常了不起的工作。但是,这种压力在这里停止,无法再忽视它们。冷酷的事实是,让每个人都快乐是完全不可能的。框架没有合理的方式来猜测MMF另一端的代码是什么样的。不可知的是,MMF完全过于简单,无法支持任何元数据。在一端有32位进程而另一端有64位进程的清除故障模式下,他们使用不同的对齐选择,4对8。更多,特别是如果它是使用其自己的#pragma包的另一端的本机代码。

鉴于框架永远无法100%正确,他们选择了至少使.NET代码在任何一方运行时都是正确和有效的。一个完全合理的选择。

唯一真正的缺陷是文档缺乏。当您需要与本机代码进行互操作时,您的头痛。尝试和错误是现在唯一的好方法。或者询问一个关于特定问题的问题,当然你也有:)

+0

_“该框架没有合理的方法来猜测MMF另一侧的代码是什么样的”_I ____ _ _ _ _ _ _ _ _ _ m不使用内存映射文件。我使用了一个自定义的SafeBuffer子类来包装一些无人的内存。 B.如果CLR无法猜测,它至少可以让客户端指定它想要的对齐方式。事实上,我应该能够通过StructLayoutAttribute来设置结构的大小和内存布局,这表明它在转换为指针时会受到尊重。 – Benjamin 2014-09-04 18:50:46

+0

你当然在跟错误的人说话。改用微软。或者只是编写你自己的SafeBuffer版本。 – 2014-09-04 18:52:55

+0

我来这里看看我是否脱离基地。对不起,如果它看起来像我争论。无论如何,我最终可能会与微软交谈并编写自己的版本。谢谢您的帮助。 – Benjamin 2014-09-04 19:59:33

相关问题