简体   繁体   English

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

[英]Why is BSTR length prefix 4 bytes on 64-bit platforms?

It seems that on 64-bit platforms it would be reasonable to have a 8-byte length prefix.似乎在 64 位平台上使用 8 字节长度的前缀是合理的。 If we can address more than 4Gb of mem why not allow, say, 5Gb strings?如果我们可以处理超过 4Gb 的内存,为什么不允许使用 5Gb 字符串? Is the answer just "by specification" or there is some interoperability/backwards compatibility reasons that I'm not aware of?答案只是“按规范”还是有一些我不知道的互操作性/向后兼容性原因? Thanks.谢谢。

The BSTR data type is the standard COM string data type. BSTR数据类型是标准的 COM 字符串数据类型。 Changing the length prefix would make it impossible to safely move strings between processes of different bitness (or at least make it significantly more complex).更改长度前缀将无法在不同位数的进程之间安全地移动字符串(或至少使其变得更加复杂)。 Since COM is the only relevant cross-bitness interop infrastructure it is necessary to have BSTR s behave the same way for 32-bit processes and 64-bit processes.由于 COM 是唯一相关的跨位互操作基础设施,因此有必要让BSTR的行为方式与 32 位进程和 64 位进程相同。

It is a tradeoff, imposing a 'limit' of 2GB in exchange for hassle-free marshaling of strings between processes of different bitness.这是一种权衡,强加 2GB 的“限制”以换取不同位元进程之间的字符串无障碍编组。

One good reason is for compatibility with platform APIs like MultiByteToWideChar which accepts int lengths.一个很好的理由是与平台 API 兼容,例如接受int长度的MultiByteToWideChar There are many more string APIs that work with 32 bit lengths.还有更多的字符串 API 可以使用 32 位长度。

It's not actually a real limitation because I cannot conceive of a scenario where a BSTR of length >2GB would be the best solution to a problem.这实际上并不是真正的限制,因为我无法想象长度 >2GB 的BSTR将是解决问题的最佳方案的场景。

BSTR is a length-prefixed string , so the first property is length , not address. BSTR是一个以长度为前缀的字符串,所以第一个属性是长度,而不是地址。 Therefore it need not be the same size as the pointer and can just be the size that's enough for the application因此它不需要与指针大小相同,并且可以是应用程序足够的大小

For all practical purposes, 4GB is more than enough for a string, and keeping the maximum string size the same allows you to pass strings between processes without problem.对于所有实际目的,4GB 对一个字符串来说已经足够了,并且保持最大字符串大小相同可以让您在进程之间毫无问题地传递字符串。 For example if the length is a 64-bit type on 64-bit Windows then what will happen when you pass an 8GB string from a 64-bit process to a 32-bit process?例如,如果长度是 64 位 Windows 上的 64 位类型,那么当您将 8GB 字符串从 64 位进程传递到 32 位进程时会发生什么? Should the string be truncated or should an error be reported?字符串应该被截断还是应该报告错误? The same prefix size may also improve backward compatibility相同的前缀大小还可以提高向后兼容性

The most important reason is probably so that BSTR can continue to travel in VARIANT .最重要的原因可能是为了让 BSTR 可以继续在VARIANT旅行。 You will notice from the definition of tagVARIANT in oaidl.h that the bstrVal member appears to be part of the union of other types, but where is its length stored?你会从定义注意到tagVARIANT在OAIDL.H的bstrVal成员似乎是其他类型的联盟的一部分,而是保存它的长度在哪里呢? The answer is in the wReserved2 / wReserved3 members of the VARIANT structure that immediately precede the bstrVal member in memory.答案是在wReserved2 / wReserved3的成员VARIANT结构立即先于bstrVal在存储器部件。 There are 3 reserved words there so in theory BSTR's length could be expanded to 6 bytes, but if it got any bigger it would overwrite the VARTYPE member and VARIANT would no longer work.那里有 3 个保留字,所以理论上 BSTR 的长度可以扩展到 6 个字节,但是如果它变得更大,它将覆盖VARTYPE成员并且 VARIANT 将不再起作用。 So BSTR is length-limited even on 64-bit platforms so that it can continue to travel in VARIANT .所以BSTR即使在 64 位平台上也有长度限制,以便它可以继续在VARIANT传播。

The range of applications where it's useful to have a large number of objects whose total size exceeds 2GiB is much greater than the range of applications where it's useful to either have any individual objects exceed 2GiB.拥有大量总大小超过 2GiB 的对象有用的应用程序范围远大于拥有任何单个对象超过 2GiB 的应用程序范围。 Even if individual operations on 64-bit values are no more expensive than operations on 32-bit values, the number of 32-bit values that will fit in each level of cache will be twice the number of 64-bit values likewise.即使对 64 位值的单个操作并不比对 32 位值的操作更昂贵,但适合每一级缓存的 32 位值的数量同样是 64 位值的数量的两倍。 Thus, absent a good reason to use 64-bit values to hold object sizes, having a platform limit individual objects to 2GiB is a perfectly reasonable design decision, especially since code which isn't designed to work with larger objects will often malfunction in ways that would be prone to creating security vulnerabilities if run on systems that don't reject attempts to create objects greater than 2GiB.因此,如果没有使用 64 位值来保存对象大小的充分理由,让平台将单个对象限制为 2GiB 是一个完全合理的设计决策,特别是因为不是设计用于处理更大对象的代码通常会出现故障如果在不拒绝尝试创建大于 2GiB 的对象的系统上运行,则很容易产生安全漏洞。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM