:: Не фоксом единым
Небезопасный буфер
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
На msdn.microsoft.com есть пример. Пример запускается, работает, но ни чего не выводит. Попробовал добавить в пример Console.WriteLine - не получилось:

unsafe struct MyBuffer
{
public fixed char fixedBuffer[10];
}
unsafe class MyClass
{
public MyBuffer myBuffer = default(MyBuffer);
}
static void Main()
{
MyClass myC = new MyClass();
unsafe
{
fixed (char* charPtr = myC.myBuffer.fixedBuffer)
{
*charPtr = 'A';
}
Console.WriteLine(new string(myC.myBuffer.fixedBuffer)); // ошибка
}
Console.ReadLine();
}

Ругается:

Цитата:
Невозможно использовать буферы фиксированного размера в нефиксированных выражениях. Попробуйте использовать оператор fixed.

Вопрос - как можно вывести "A"?
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Если упростить пример, то работает:

unsafe struct MyBuffer
{
public fixed char fixedBuffer[10];
}
static void Main()
{
MyBuffer myBuffer = default(MyBuffer);
unsafe
{
char* charPtr = myBuffer.fixedBuffer;
*charPtr = 'A';
Console.WriteLine(new string(myBuffer.fixedBuffer)); // "A"
}
Console.ReadLine();
}
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Т.е. во втором примере "небезопасный буфер" спокойно преобразуется в строку. А в первом примере почему то ругается...
Ratings: 0 negative/0 positive
Небезопасный буфер
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
С некоторых пор появился stackoverflow на русском. Для пробы задал там этот вопрос ru.stackoverflow.com Посмотрим, что ответят.
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Ответили уже


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Угу... Аж 4-ре раза... Сначала хотел написать, что "прежде чем дать совет - попробуй сам", но - решил ещё подождать.

Как то на хабре была статья (переводная) "Закат Stack Overflow" habrahabr.ru
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
А зачем тебе это вообще понадобилось? Фишка нужна только для взаимодействия с неуправляемым кодом, при том весьма специфическим - структуры со "встроенными" массивами...

Конкретно "как вывести"
Console.WriteLine(new string(charPtr));
естественно внутри fixed блока, где charPtr ещё определена. Т.к. этот указатель "зафиксирован" его использовать можно.

И использовать лучше перегрузку конструктора string принимающую ещё и смещение и размер буфера - т.к. если заполнить все 10 элементов, то нет гарантии что после этого массива окажется юникодный nul-символ, и "строка" может всякого мусора захватить в себя.
Кстати, и прочих обычных "проверок и ограничений" этот небезопасный код не делает - например можно запросто присвоить значение 11-му элементу массива - т.е. записать данные ВНЕ его границ MSDN просто советует быть предельно осторожным - ну как в фоксе при работе с SYS(2600) записывающей что-либо в память.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
Конкретно "как вывести"
Console.WriteLine(new string(charPtr));
естественно внутри fixed блока, где charPtr ещё определена. Т.к. этот указатель "зафиксирован" его использовать можно.

Вывести именно fixedBuffer (как это сделано во 2-м примере), а не charPtr.
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
А зачем тебе это вообще понадобилось?
Всегда интересно, почему код не заработал. IMHO, код

new string(myC.myBuffer.fixedBuffer)

не должен порождать проблем.



Исправлено 1 раз(а). Последнее : S-type, 27.03.17 20:49
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
2-й пример работает с value type, а первый - с reference type (он является перемещаемым, и, соответственно, структура внутри него тоже) - поэтому для него требуется "фиксация". Ну по крайней мере я так это понимаю.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Выходит, до myC.myBuffer.fixedBuffer не достучаться...
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Напрямую через "кучу точек" наверное нет, а так - сделай себе копию структуры (она попадёт уже в стек и будет "неперемещаемой", т.е. не требующей "фиксации" для получения указателя) и будет по сути так же как в "варианте 2".
MyBuffer tmp = myC.myBuffer;
Console.WriteLine(new string(tmp.fixedBuffer));

Только занафига это нужно, если под рукой уже есть готовый указатель char* charPtr - и он надлежащим образом "зафиксирован"? Точнее зафиксирован экземпляр класса, что и позволяет получать указатель на хранящуюся внутри него структуру.
Кстати, эти fixed массивы тоже своего рода синтаксический сахар - в откомпилированном коде оно выглядит несколько иначе...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
Напрямую через "кучу точек" наверное нет, а так - сделай себе копию структуры (она попадёт уже в стек и будет "неперемещаемой", т.е. не требующей "фиксации" для получения указателя) и будет по сути так же как в "варианте 2".
MyBuffer tmp = myC.myBuffer;
Console.WriteLine(new string(tmp.fixedBuffer));

Гениально...
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Опубликовал ответ на ru.stackoverflow.com , при этом честно указал, что мне помогли. Но, мой ответ почему то подкорректировали. В итоге, у меня сейчас в карме 16 и два каких то бронзовых знака.
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
S-type
сейчас в карме 16 и два каких то бронзовых знака.


Большому кораблю - большая торпеда большое плавание!.. :bi:
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Самому страшно
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
А чего второй вариант не привёл - он ведь более оптимален, не требует копирования структуры, да и в общем как-то более логичен...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
А чего второй вариант не привёл

Речь о

Console.WriteLine(new string(charPtr));
?
Мне кажется, он интуитивно понятен. По крайней мере, это было первое, что мне пришло в голову. И уж потом родилась грешная мысль "а если без charPtr".
Ratings: 0 negative/0 positive
Re: Небезопасный буфер
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Ну на том сайте он явно "не понятен" т.к. никто не предложил. Даже тот кто говорил о переносе cw внутрь fixed блока


------------------
WBR, Igor
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 2 (Гостей: 2)

© 2000-2024 Fox Club 
Яндекс.Метрика