преобразование System::String в wchar_t* — как определяется конец?

#.net #visual-c #c -cli #interop

#.net #visual-c #c -cli #взаимодействие

Вопрос:

Процесс объясняется здесь:http://msdn.microsoft.com/en-US/library/d1ae6tz5(v=VS.80).aspx Чего я не понял из этой статьи, так это того, что закрепленный wchar_t * передается различным строковым функциям C, которые полагаются на завершающий нулевой символ. Это правило, которое .ЧИСТЫЕ строки имеют завершающий нулевой символ? Система.В документах String говорится, что:

В .NET Framework нулевой символ может быть встроен в строку. Когда строка содержит один или более нулевых символов, они включаются в длину общей строки.

Ответ №1:

Насколько я понимаю, внутренний буфер символов в строках .NET CLR заканчивается нулем, хотя, естественно, этот нулевой символ не включается в число символов, поэтому любой .СЕТЕВОЙ код проигнорировал бы это. Значение null используется только для упрощения взаимодействия с Windows API или другим простым кодом C, который ожидает, что строки будут заканчиваться нулем. Вместо добавления нулевого символа каждый раз, когда строка .NET должна быть передана в C API (и, возможно, для перераспределения и копирования всей строки), нулевой символ просто присутствует с самого начала — полезная оптимизация в реальном мире, поскольку .СЕТИ все еще приходится выполнять множество взаимодействий за кулисами, даже если вы не используете это явно.

Если у вас действительно есть несколько нулевых символов в середине вашей строки, что ж, любой C API, который получает вашу строку, вероятно, остановится на этом и никогда не достигнет конца строки. Я думаю, вы даже можете попробовать это в C / CLI самостоятельно и посмотреть, что получится. 🙂

Комментарии:

1. На самом деле, когда я извлекаю wchar_t * из System:: String, я вижу пару ненужных символов после конца текста и перед нулевым символом. Возможно, это как-то связано с тем фактом, что строка поступает из Windows. Формы. Текстовое поле?

2. Возможно, хотя я действительно не вижу причины, почему. Текст окна. Формы. Текстовое поле, безусловно, должно проходить через Windows API (что потребовало бы, чтобы оно заканчивалось нулем) где-то, но я не знаю, почему вы получите там мусор.

Ответ №2:

Просто догадываюсь, потому что у меня нет доступа к внутренним функциям Microsoft.

Это явно не указано, но строка wchar_t * всегда должна заканчиваться нулевым символом. Пример поддерживает это, поскольку он использует printf_s функцию, которая зависит от этой характеристики.

PtrToStringChars Функция предоставляет доступ к внутреннему буферу строк. Функция может добавлять нулевой символ в буфер, не включая его в число символов строки, таким образом .Пользователи сети, использующие строку, не увидели бы значение null.

Комментарии:

1. Функция PtrToStringChars() определена во включаемом файле vcclr.h , так что вы можете посмотреть на нее самостоятельно. Похоже, что он не добавляет символы в строковый буфер и не изменяет его каким-либо образом. Это просто дает вам указатель на внутренний буфер символов.

2. @Boaz Yaniv, спасибо за ссылку. Я также не вижу никаких добавлений. Я должен предположить, что другие строковые функции поддерживают значение null в конце буфера, не включая его в число символов.

3. Об этом почти нет никакой информации, но несколько статей, которые я нашел, в которых обсуждается проблема, кажется, указывают на это .