![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
как тип String привести к PWideChar?
Yandexman © (2005-06-01 19:05:00)как String привести к PWideChar?
Ученик (2005-06-08 22:28:00) [1]>Alex Konshin © (08.06.05 14:03) [28]
>Но кто даст гарантию?
Borland
>а по семантике должно быть так, как я говорю.
Где это документировано ?
Alex Konshin (2005-06-08 14:03:00) [2]Это тут ни при чем. Дело не в оптимизации, а в использовании грязной памяти.
Ученик (02.06.05 21:39) [23]
>Alex Konshin © (02.06.05 11:54) [22]
Вы не правы, в той точке будет все нормально, достаточно посмотреть CPU.
В этой точке - да, сам знаю. Но кто даст гарантию? Это в любом случае недокументировано, а по семантике должно быть так, как я говорю. Следовательно, даже если это так сейчас и при таких опциях компилятора, то может быть иначе в следующей версии или при других опциях. А будет что-нибудь посложнее одного выражения и там точно будет эта проблема. Хочешь рисковать - пожалуйста. Но я не вижу в этом смысла. Можно же просто избежать эти сомнительные приемы без потери и скорости, и читаемости.
Yandexman (2005-06-08 13:42:00) [3]Никуда она не освобождается, оптимизация памяти ведь тоже не дураками писана, если не исплозуется то освобождается, а иначе хранится, вы сами отладчиком проверьте
Ученик (2005-06-03 07:32:00) [4]>Yandexman (03.06.05 06:39) [25]
Caption тут не причем, речь идет о памяти, выделенной для преобразования s: string в WideString, она освобождается при выходе из процедуры (функции).
Yandexman (2005-06-03 06:39:00) [5]
> вправе выделить эту память под что-нибудь другое.
Не вправе, так как Caption ни куда не исчезло, и сущесивует до самого конца, вы сами попробуйте :-)
VMcL (2005-06-02 23:58:00) [6]>> Alex Konshin © (02.06.05 11:54) [22]
AFAIR, на практике, строки и интерфейсы финализируются в конце функции в скрытой секции finally. Не знаю, описано ли это в справке.
Ученик (2005-06-02 21:39:00) [7]>Игорь Шевченко © (02.06.05 10:11) [20]
Не знаю, а Вы ?
>Alex Konshin © (02.06.05 11:54) [22]
Вы не правы, в той точке будет все нормально, достаточно посмотреть CPU.
Alex Konshin (2005-06-02 11:54:00) [8]jack128 © (02.06.05 10:07) [19]
Ну ты прямо как маленький. Да, не актуален. И если у тебя там что-нибудь посложнее присваивания и включена оптимизация компилятор вправе финализировать тот временный WideString сразу после его использования и менеджер памяти вправе выделить эту память под что-нибудь другое.
То есть нарваться на это вполне реально. Я бы не стал забиваться на то, что это не случиться, и уж тем более учить этому других не буду. Тем более что в твоем примере избавиться от этого потенциально опасного кода - элементарно:
var
w : WideString;
begin
w := StringOfChar('a', 10);
Caption := PWideChar(w); // неясно зачем, но ты так хотел
end;
Yandexman (2005-06-02 11:33:00) [9][2] мне прекрасно подошло.
Игорь Шевченко (2005-06-02 10:11:00) [10]Ученик (02.06.05 08:21) [18]
> К тому же память, выделенная в стеке, не всегда подходит
> для вызова функций Windows ("по следам" обсуждения в Windows
> API вызова ZwQueryObject).
А почему не подходит, можно узнать ? :)
С уважением,
jack128 (2005-06-02 10:07:00) [11]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 08:21:00) [12]>Alex Konshin © (02.06.05 00:41) [15]
Заботиться об обращениях в менеджеру памяти конечно можно, но как быть тогда с string.
К тому же память, выделенная в стеке, не всегда подходит для вызова функций Windows ("по следам" обсуждения в Windows API вызова ZwQueryObject).
nikkie (2005-06-02 00:47:00) [13]ой, сорри :))
невнимательно код прочитал.
nikkie (2005-06-02 00:46:00) [14]>В данном случае вполне сойдет и 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;
Alex Konshin (2005-06-02 00:41:00) [15]Зато так эффективнее - нет обращений к менеджеру памяти.
Ученик (2005-06-02 00:27:00) [16]>Игорь Шевченко © (02.06.05 00:22) [13]
В данном случае вполне сойдет и VMcL © (01.06.05 19:09) [2]
текста меньше однозначно
Игорь Шевченко (2005-06-02 00:22:00) [17]Ученик (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;
Eraser (2005-06-02 00:16:00) [18]Вот кусок из справки:
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:11:00) [19]>Игорь Шевченко © (02.06.05 00:01) [10]
В контексте Alex Konshin © (01.06.05 23:12) [8]
c этим тоже могут быть проблемы :-)
Игорь Шевченко (2005-06-02 00:01:00) [20]В SysUtils есть нужная функция StringToWideChar