为什么在64位平台上BSTR长度前缀为4个字节?

时间:2014-04-16 04:00:46

标签: c winapi 64-bit 32bit-64bit bstr

似乎在64位平台上,有一个8字节长度的前缀是合理的。如果我们可以解决超过4Gb的内存,为什么不允许,比如5Gb字符串?答案只是“按规范”还是存在一些我不知道的互操作性/向后兼容性原因? 感谢。

5 个答案:

答案 0 :(得分:7)

BSTR数据类型是标准COM字符串数据类型。更改长度前缀将使得无法在不同位数的进程之间安全地移动字符串(或者至少使其更加复杂)。由于COM是唯一相关的跨位互操作基础结构,因此BSTR对于32位进程和64位进程的行为必须相同。

这是一种权衡,强加了2GB的“限制”,以换取不同位数进程之间无障碍的字符串编组。

答案 1 :(得分:5)

一个很好的理由是与MultiByteToWideChar等接受int长度的平台API兼容。还有许多字符串API可以使用32位长度。

这实际上并不是一个真正的限制,因为我无法想象BSTR长度> 2GB的情况是解决问题的最佳方案。

答案 2 :(得分:1)

BSTRlength-prefixed string,因此第一个属性是 length ,而不是地址。因此它不需要与指针大小相同,并且只能是应用程序的足够大小

出于所有实际目的,4GB对于字符串来说已经足够了,并且保持最大字符串大小相同允许您在进程之间传递字符串而没有问题。例如,如果64位Windows上的长度是64位类型,那么当您将8位字符串从64位进程传递到32位进程时会发生什么?字符串应该被截断还是应该报告错误?相同的前缀大小也可以改善向后兼容性

答案 3 :(得分:0)

最重要的原因可能是BSTR可以继续以VARIANT运行。从oaidl.h中tagVARIANT的定义中,您会注意到bstrVal成员似乎是其他类型的并集的一部分,但是其长度存储在哪里?答案是在内存中紧接bstrVal成员的VARIANT结构的wReserved2 / wReserved3成员中。那里有3个保留字,因此从理论上讲BSTR的长度可以扩展到6个字节,但如果更大,它将覆盖VARTYPE成员,而VARIANT将不再起作用。因此,即使在64位平台上,BSTR也是受长度限制的,因此它可以继续在VARIANT中运行。

答案 4 :(得分:0)

拥有大量总大小超过2GiB的对象的应用程序范围比拥有任何单个对象超过2GiB的应用程序范围大得多。即使对64位值进行的单个操作并不比对32位值进行的操作昂贵,但将适合每个缓存级别的32位值的数量也将是64位值的数量的两倍。因此,缺少使用64位值来保存对象大小的充分理由,并且将平台对象单个限制为2GiB是一个完全合理的设计决定,尤其是因为未经设计的代码如果在不拒绝尝试创建大于2GiB的对象的系统上运行,则使用较大的对象通常会以易于制造安全漏洞的方式发生故障。