Se debe establecer StringBuilder.Capacity
en la cantidad máxima de caracteres .NET, sin tener en cuenta la terminación nula, o se debe establecer uno más alto para reservar espacio para un terminador nulo cuando se usa P/Invoke.¿Cuál es la forma correcta de establecer StringBuilder.Capacity cuando se usa P/Invoke?
La reacción natural es que se debe establecer uno más alto, pero parece que se espera que P/Invoke compense automáticamente. De hecho, este es en realidad documentada aquí: http://msdn.microsoft.com/en-US/library/s9ts558h(v=VS.100).aspx
La razón de esta pregunta es que la mayoría de los ejemplos no son estrictamente coherente con la documentación anterior. Casi siempre se codifican:
StringBuilder sb = new StringBuilder(dotNetChars + 1);
SomeWindowsAPI(sb, sb.Capacity);
En lugar de:
StringBuilder sb = new StringBuilder(dotNetChars);
SomeWindowsAPI(sb, sb.Capacity + 1);
(Soy consciente de que algunas API manejan el parámetro de tamaño de búfer diferente Supongamos que la API se encarga de esta forma común del mosto, como GetFullPathName
.: http://msdn.microsoft.com/en-us/library/aa364963(v=VS.85).aspx)
Usar una expresión con sb.Capacity
directamente en la llamada API parece ser una buena práctica para evitar una falta de coincidencia. El problema es si agregar o no el +1 es correcto.
Mire a su alrededor. Probablemente descubrirá que el único lugar que muestra sb.Capacity + 1
es la documentación de MSDN.
Por supuesto, se puede asignar precaución con un búfer más grande que el estrictamente necesario, pero me gustaría saber el consenso sobre cómo hacerlo.
¿Pero qué hace P/Invoke con esto? Si P/Invoke solo pasa la dirección del primer carácter en ese conjunto a la función externa, entonces el conjunto es 1 demasiado corto para el terminador nulo. –
Las cadenas se organizan para pinvoke y el marco agrega automáticamente cosas como '\ 0'. Creo que en este caso, no tiene que tener eso en cuenta. –