Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么64位平台上的BSTR长度前缀为4字节?_C_Winapi_64 Bit_32bit 64bit_Bstr - Fatal编程技术网

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

C 为什么64位平台上的BSTR长度前缀为4字节?,c,winapi,64-bit,32bit-64bit,bstr,C,Winapi,64 Bit,32bit 64bit,Bstr,似乎在64位平台上,使用8字节长度的前缀是合理的。如果我们可以处理超过4Gb的内存,为什么不允许(比如)5Gb字符串?答案是“按规范”还是有一些互操作性/向后兼容性的原因我不知道? 谢谢。是a,所以第一个属性是长度,而不是地址。因此,它不必与指针大小相同,只需是应用程序所需的大小即可 对于所有实际用途,4GB对于字符串来说已经足够了,保持最大字符串大小不变可以让您在进程之间毫无问题地传递字符串。例如,如果64位Windows上的长度是64位类型,那么将8GB字符串从64位进程传递到32位进程时会

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

是a,所以第一个属性是长度,而不是地址。因此,它不必与指针大小相同,只需是应用程序所需的大小即可


对于所有实际用途,4GB对于字符串来说已经足够了,保持最大字符串大小不变可以让您在进程之间毫无问题地传递字符串。例如,如果64位Windows上的长度是64位类型,那么将8GB字符串从64位进程传递到32位进程时会发生什么情况?字符串应该被截断还是应该报告错误?相同的前缀大小也可以提高向后兼容性

一个很好的原因是与平台API(如
MultiByteToWideChar
)兼容,后者接受
int
长度。还有更多的字符串API使用32位长度


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

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


这是一种折衷,施加2GB的“限制”,以换取在不同比特数的进程之间对字符串进行无麻烦的封送处理。

最重要的原因可能是为了使BSTR可以继续以变体形式传输。从oaidl.h中tagVARIANT的定义中,您会注意到bstrVal成员似乎是其他类型联合的一部分,但其长度存储在哪里?答案在变体结构的wReserved2/wReserved3成员中,该成员位于内存中bstrVal成员的前面。那里有3个保留字,所以理论上BSTR的长度可以扩展到6字节,但如果它再大一点,就会覆盖VARTYPE成员,VARIANT将不再工作。所以,即使在64位平台上,BSTR的长度也是有限的,所以它可以继续以不同的方式传输

总大小超过2GiB的对象数量多的应用范围远大于单个对象超过2GiB的应用范围。即使对64位值的单独操作并不比对32位值的操作更昂贵,但适合每个缓存级别的32位值的数量也将是64位值数量的两倍。因此,在没有充分理由使用64位值来保持对象大小的情况下,让平台将单个对象限制为2GiB是一个完全合理的设计决策,特别是,如果在不拒绝创建大于2GiB的对象的系统上运行,则设计用于处理较大对象的代码通常会以容易产生安全漏洞的方式出现故障。

我已编辑了该问题。我想问的是为什么不用一个size\u t而不是一个4字节的int。谢谢。我不知道您可以在32位和64位进程之间传递BSTR。BSTR如何在不重新分配的情况下从32位进程传递到64位进程?@David reallocation or not,
BSTR
的布局有文档记录。自定义封送拆收器和系统提供的封送拆收器都依赖于这种有文档记录的布局:指向数据字符串的指针,该数据字符串的前缀为4字节,紧跟在内存中该数据的前面。考虑在共享内存中保持其状态的对象的优化封送器。如果该内存映射到两个进程中,则不能为不同的位使用具有不同内存布局的
BSTR
s。