Маршалинг данных между управляемым и неуправляемым кодом - Маршалинг и класс StringBuilder

ОГЛАВЛЕНИЕ


Маршалинг и класс StringBuilder

В компоненте маршалинга в среде CLR имеются встроенные сведения о существовании типа StringBuilder, потому он обрабатывается не так, как все остальные типы. По умолчанию класс StringBuilder передается с обоими атрибутами [InAttribute, OutAttribute]. Класс StringBuilder обрабатывается по-другому, потому что у него есть свойство Capacity, которое определяет необходимый размер буфера и может динамически изменяться. По этой причине во время выполнения маршалинга среда CLR может зафиксировать класс StringBuilder, передать напрямую адрес внутреннего буфера, используемый в классе StringBuilder, и позволить машинному коду изменять содержимое буфера.

Чтобы использовать все возможности класса StringBuilder в полной мере, нужно соблюдать следующие правила:

  1. Не передавайте класс StringBuilder по ссылке (с использованием ключевых слов out и ref). В противном случае среда CLR будет считать, что аргумент имеет сигнатуру wchar_t **, а не wchar_t *, и не сможет зафиксировать внутренний буфер класса StringBuilder. В результате значительно снизится производительность.
  2. Применяйте класс StringBuilder, если в неуправляемом коде используется Юникод. В противном случае среде CLR придется создавать копию строки и перекодировать ее из Юникода в ANSI и обратно, что также снизит производительность. Обычно при маршалинге класс StringBuilder представляется в виде массива LPARRAY, состоящего из символов Юникода, или в виде строки LPWSTR.
  3. Всегда заранее указывайте емкость StringBuilder и проверяйте, хватает ли ее для буфера. На стороне неуправляемого кода лучше всего принять в качестве аргумента размер буфера строки — так вы избежите переполнения буфера. В модели COM указать размер можно также при помощи size_is в IDL.