Форум: "Основная";
Текущий архив: 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.039 c