Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];

Вниз

как тип String привести к PWideChar?   Найти похожие ветки 

 
Yandexman   (2005-06-01 19:05) [0]

как String привести к PWideChar?


 
Reindeer Moss Eater ©   (2005-06-01 19:08) [1]

Явно


 
VMcL ©   (2005-06-01 19:09) [2]

PWideChar(WideString(S))
где S - AnsiString


 
Alex Konshin ©   (2005-06-01 22:46) [3]

При таком явном приведении может быть memory leak или к обращению к мусору.
Так же как и при простом PChar(s).

Мастера, тщательнее надо быть, тщательнее. :)


 
VMcL ©   (2005-06-01 22:49) [4]

>>Alex Konshin ©   (01.06.05 22:46) [3]

А ещё кирпич на голову может упасть.

WBW.


 
Ученик   (2005-06-01 22:50) [5]

>Alex Konshin ©   (01.06.05 22:46) [3]

Вы это серьезно ?


 
iskatel ©   (2005-06-01 22:56) [6]

2Alex Konshin
тебе надо на сях попрограммить или на асме, а то вообще всего боятся стал, что в хелпе как не "safe" прописано :-)


 
Reindeer Moss Eater ©   (2005-06-01 22:58) [7]

Даже если будет утечка памяти или обращение к мусору или даже если упадет кирпич, приведение string к PWideChar все равно состоится.
А о другом  не спрашивалось.
:)


 
Alex Konshin ©   (2005-06-01 23:12) [8]

Ученик   (01.06.05 22:50) [5]
>Alex Konshin ©   (01.06.05 22:46) [3]
Вы это серьезно ?

Вполне серьезно.

Вот, например, такое безобидное применение (кстати, первое же, что напрашивается в голову начинающему) предложенного способа чревато любыми неприятностями.

function ToWideChar( const S: String ) : PWideChar;
begin
 Result := PWideChar(WideString(S));
end;

Вы хоть предупреждайте новичков.

Для тех, кто не понял: актуальность указателя, получаемого по PWideChar(WideString(S)) практически только в пределах самого этого выражения. Передавать его куда-либо нельзя.


 
Ученик   (2005-06-01 23:55) [9]

>Alex Konshin ©   (01.06.05 23:12) [8]

Понятно :-)

Есть предположение, что Yandexman спрашивает для этого

http://delphimaster.net/view/4-1117616006/


 
Игорь Шевченко ©   (2005-06-02 00:01) [10]

В SysUtils есть нужная функция StringToWideChar


 
Ученик   (2005-06-02 00:11) [11]

>Игорь Шевченко ©   (02.06.05 00:01) [10]
В контексте Alex Konshin ©   (01.06.05 23:12) [8]
c этим тоже могут быть проблемы :-)


 
Eraser ©   (2005-06-02 00:16) [12]

Вот кусок из справки:

A common error when working with PChars is to store a local variable in a data structure, or return it as a value. When your routine ends, the PChar disappears because it is a pointer to memory, and not a reference counted copy of the string. For example:

function title(n: Integer): PChar;
var
 s: string;
begin
 s := Format("title - %d", [n]);
 Result := PChar(s); // DON"T DO THIS
end;

This example returns a pointer to string data that is freed when the title function returns.


 
Игорь Шевченко ©   (2005-06-02 00:22) [13]

Ученик   (02.06.05 00:11) [11]


> В контексте Alex Konshin ©   (01.06.05 23:12) [8]
> c этим тоже могут быть проблемы :-)


Нет, там проблем не будет, там буфер под результирующую строку передается функции :)

Я вот так пользуюсь:

procedure TFSDDirectoryHelper.Open(const DeviceName: string);
var
 NameBuffer: array[0..255] of WideChar;
 InternalDeviceName: string;
 Status: NTSTATUS;
begin
 InternalDeviceName := Format("\Device\%s\", [DeviceName]);
 Status := InternalOpen(StringToWideChar(InternalDeviceName,
   NameBuffer, SizeOf(NameBuffer)
), FILE_READ_ATTRIBUTES or FILE_READ_EA);
 if not NT_SUCCESS(Status) then
   RaiseNtError(Status);
end;


 
Ученик   (2005-06-02 00:27) [14]

>Игорь Шевченко ©   (02.06.05 00:22) [13]

В данном случае вполне сойдет и VMcL ©   (01.06.05 19:09) [2]
текста меньше однозначно


 
Alex Konshin ©   (2005-06-02 00:41) [15]

Зато так эффективнее - нет обращений к менеджеру памяти.


 
nikkie ©   (2005-06-02 00:46) [16]

>В данном случае вполне сойдет и VMcL
никак не подойдет. но мне кажется все же без StringToWideChar проще.

procedure TFSDDirectoryHelper.Open(const DeviceName: string);
var
NameBuffer: WideString;
InternalDeviceName: string;
Status: NTSTATUS;
begin
InternalDeviceName := Format("\Device\%s\", [DeviceName]);
SetLength(NameBuffer, 256);
Status := InternalOpen(PWideChar(NameBuffer), FILE_READ_ATTRIBUTES or FILE_READ_EA);
if not NT_SUCCESS(Status) then
  RaiseNtError(Status);
end;


 
nikkie ©   (2005-06-02 00:47) [17]

ой, сорри :))
невнимательно код прочитал.


 
Ученик   (2005-06-02 08:21) [18]

>Alex Konshin ©   (02.06.05 00:41) [15]
Заботиться об обращениях в менеджеру памяти конечно можно, но как быть тогда с string.

К тому же память, выделенная в стеке, не всегда подходит для вызова функций Windows ("по следам" обсуждения в Windows API  вызова ZwQueryObject).


 
jack128 ©   (2005-06-02 10:07) [19]

Alex Konshin ©   (01.06.05 23:12) [8]
актуальность указателя, получаемого по PWideChar(WideString(S)) практически только в пределах самого этого выражения.

var
 WP: PWideChar;
 s: string;
begin
 s := StringOfChar("a", 10);
 WP := PWideChar(WideString(s)); // WP актуален только в приделах этого выражения??
 Caption := WP; // Вот здесь он уже не актуален???
end;


 
Игорь Шевченко ©   (2005-06-02 10:11) [20]

Ученик   (02.06.05 08:21) [18]


> К тому же память, выделенная в стеке, не всегда подходит
> для вызова функций Windows ("по следам" обсуждения в Windows
> API  вызова ZwQueryObject).


А почему не подходит, можно узнать ? :)

С уважением,


 
Yandexman   (2005-06-02 11:33) [21]

[2] мне прекрасно подошло.


 
Alex Konshin ©   (2005-06-02 11:54) [22]

jack128 ©   (02.06.05 10:07) [19]
Ну ты прямо как маленький. Да, не актуален. И если у тебя там что-нибудь посложнее присваивания и включена оптимизация компилятор вправе финализировать тот временный WideString сразу после его использования и менеджер памяти вправе выделить эту память под что-нибудь другое.
То есть нарваться на это вполне реально. Я бы не стал забиваться на то, что это не случиться, и уж тем более учить этому других не буду. Тем более что в твоем примере избавиться от этого потенциально опасного кода - элементарно:

var
 w : WideString;
begin
 w := StringOfChar("a", 10);
 Caption := PWideChar(w); // неясно зачем, но ты так хотел
end;


 
Ученик   (2005-06-02 21:39) [23]

>Игорь Шевченко ©   (02.06.05 10:11) [20]
Не знаю, а Вы ?

>Alex Konshin ©   (02.06.05 11:54) [22]
Вы не правы, в той точке будет все нормально, достаточно посмотреть CPU.


 
VMcL ©   (2005-06-02 23:58) [24]

>>Alex Konshin ©   (02.06.05 11:54) [22]

AFAIR, на практике, строки и интерфейсы финализируются в конце функции в скрытой секции finally. Не знаю, описано ли это в справке.


 
Yandexman   (2005-06-03 06:39) [25]


> вправе выделить эту память под что-нибудь другое.

Не вправе, так как Caption ни куда не исчезло, и сущесивует до самого конца, вы сами попробуйте :-)


 
Ученик   (2005-06-03 07:32) [26]

>Yandexman   (03.06.05 06:39) [25]
 Caption тут не причем, речь идет о памяти, выделенной для преобразования s: string в WideString, она освобождается при выходе из процедуры (функции).


 
Yandexman   (2005-06-08 13:42) [27]

Никуда она не освобождается, оптимизация памяти ведь тоже не дураками писана, если не исплозуется то освобождается, а иначе хранится, вы сами отладчиком проверьте


 
Alex Konshin ©   (2005-06-08 14:03) [28]

Это тут ни при чем. Дело не в оптимизации, а в использовании грязной памяти.

Ученик   (02.06.05 21:39) [23]
>Alex Konshin ©   (02.06.05 11:54) [22]
Вы не правы, в той точке будет все нормально, достаточно посмотреть CPU.

В этой точке - да, сам знаю. Но кто даст гарантию? Это в любом случае недокументировано, а по семантике должно быть так, как я говорю. Следовательно, даже если это так сейчас и при таких опциях компилятора, то может быть иначе в следующей версии или при других опциях. А будет что-нибудь посложнее одного выражения и там точно будет эта проблема. Хочешь рисковать - пожалуйста. Но я не вижу в этом смысла. Можно же просто избежать эти сомнительные приемы без потери и скорости, и читаемости.


 
Ученик   (2005-06-08 22:28) [29]

>Alex Konshin ©   (08.06.05 14:03) [28]

>Но кто даст гарантию?
Borland

>а по семантике должно быть так, как я говорю.
Где это документировано ?



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.038 c
14-1117548364
Holy
2005-05-31 18:06
2005.06.29
Что означает номер чипсета?


1-1117631953
Ega23
2005-06-01 17:19
2005.06.29
Абсолютное значение времени


4-1114784588
Виталик
2005-04-29 18:23
2005.06.29
Соответствие классов в Delphi и Си


14-1117299874
Рулон Обоев
2005-05-28 21:04
2005.06.29
batch file


14-1117709495
Nicolaev Oleg
2005-06-02 14:51
2005.06.29
Сайт запущен :)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский