使用P/Invoke时设置StringBuilder.Capacity的正确方法是什么?

Jas*_*aty 7 .net pinvoke stringbuilder

应该StringBuilder.Capacity设置为最大.NET字符数,而不考虑空终止,或者在使用P/Invoke时,必须将其设置为更高,以便为空终止符保留空间.

自然的反应是它应该设置得更高,但似乎P/Invoke应该自动补偿.事实上,这实际上是在这里记录的:http://msdn.microsoft.com/en-US/library/s9ts558h(v = VS.100).aspx

这个问题的原因是大多数示例与上述文档并不严格一致.它们几乎总是被编码:

StringBuilder sb = new StringBuilder(dotNetChars + 1);
SomeWindowsAPI(sb, sb.Capacity);
Run Code Online (Sandbox Code Playgroud)

代替:

StringBuilder sb = new StringBuilder(dotNetChars);
SomeWindowsAPI(sb, sb.Capacity + 1);
Run Code Online (Sandbox Code Playgroud)

(我意识到一些API处理缓冲区大小参数的方式不同.假设API处理这是必须的常见方式,如GetFullPathName:http://msdn.microsoft.com/en-us/library/aa364963(v = VS.85) .aspx)

sb.Capacity直接在API调用中使用表达式似乎是避免不匹配的最佳实践.问题是添加+1是否正确.

环视四周.您可能会发现唯一显示的sb.Capacity + 1是MSDN文档.

当然,人们可以在谨慎的情况下使用比绝对必要的更大的缓冲区来分配,但我想知道如何做到这一点的共识.

小智 5

我知道你已经有五年前的答案了,但在我看来,他们并没有真正回答这个问题,他们基本上没有检查这样做是否正确就放弃了潜在的问题。

MSDN文档保证了编组将确保有足够的空间来存储完整CapacityStringBuilder加上额外的空终止。引用字符串的默认封送处理

固定长度的字符串缓冲区

[...]

解决方案是将StringBuilder缓冲区作为参数而不是字符串传递。甲的StringBuilder可以解除引用和被叫改性,只要它不超过容量的StringBuilder。也可以初始化为固定长度。例如,如果将StringBuilder缓冲区初始化为N容量,封送拆收器提供大小为 ( N +1) 个字符的缓冲区。+1 说明非托管字符串具有空终止符而StringBuilder没有。

[...]

因此,您不必担心向容量添加一个,编组器已经为您完成了这项工作。


Pie*_*kel 0

在 的构造函数中StringBuilder,容量的使用如下:

m_ChunkChars = new char[capacity];
Run Code Online (Sandbox Code Playgroud)

它与m_ChunkLength字段一起使用来确定 的内容StringBuilder。这仅描述实际字符,不包括终止字符。

所以你的答案是+ 1没有必要。