Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.06.29;
Скачать: CL | DM;

Вниз

как тип 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;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.032 c
1-1117624739
towik
2005-06-01 15:18
2005.06.29
Как можно вывести тип Множество на форму?


1-1118121208
TAN_K
2005-06-07 09:13
2005.06.29
PageControl - подсветка заголовка страницы


4-1113228229
Хинт
2005-04-11 18:03
2005.06.29
Программа не работает в WinNT


1-1117624080
Anics
2005-06-01 15:08
2005.06.29
Как отловить событие внутри родительской формы MDI приложен


14-1117819487
VEG
2005-06-03 21:24
2005.06.29
Кто заметил, когда пропал the5k.org ?