![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Работа с PChar средствами Windows (API) [D2005, XP]
Max_2006 © (2006-11-05 12:38:00)как работать с PChar в Delphi средствами Windows, т.е. API? Т.е. надо например воспользоваться API функцией GetSystemDirectory, что делать если после ее выполнения нужно выполнить что-то вроде SetLength(p, Length(p)); т.е. длина строки ранв MAX_PATH, после выполнения функции GetSystemDirectory, как обрезать строку?
var
p: PChar
begin
GetMem(p, MAX_PATH);
GetSystemDirectory(p, MAX_PATH);
...
FreeMem(p);
Работу со String и ShortString не предлагайте...
Anatoly Podgoretsky (2006-11-05 15:50:00) [21]> Max_2006 (05.11.2006 15:40:23) [23]
Опять забыл приведение сделать, а ты сам не можешь догадаться? Тогда не
стоит программировать.
Ketmar (2006-11-05 15:46:00) [22]>[21] Anatoly Podgoretsky(c) 5-Nov-2006, 15:32
>не надо же полностью все писать, кое что надо
>оставить и автору
так это ж раздел "надмозги". тут неписаными правилами думать воспрещается. равно как и читать справку/книги. а ты издеваешься...
Max_2006 (2006-11-05 15:40:00) [23]всеравно на строке N := GetSystemDirectory(S, MAX_PATH); ошибка: [Pascal Error] Unit1.pas(33): E2010 Incompatible types: 'string' and 'PAnsiChar'. А так все нормально работает:
SetLength(S, MAX_PATH);
N := GetSystemDirectory(@S[1], MAX_PATH);
SetLength(S, N);
sniknik (2006-11-05 15:40:00) [24]> а что быстрее будет работать S := PChar(S); или SetLength(S, N);?
спичка, раз...
> ошибка при компиляции: [Pascal Error] Unit1.pas(32): E2010 Incompatible types: 'string' and 'PAnsiChar'
он не учел, что функция виндовая с входным параметром PChar, и если использовать стринг то он тоже должен быть "наполненным" а не пустым (тогда можно сделать приведение типа после которого там быде во что писать функции)
вот пример "минимум"
procedure TForm1.Button1Click(Sender: TObject);итого минимум
var
a: array [0..MAX_PATH] of Char;
s: string;
n: Integer;
begin
n:= GetSystemDirectory(a, MAX_PATH);
//Win32Check(n <> 0); полезная функция но ексепты в модуле тоже SysUtils
s:= a; //и "обрезание" и присваивание
//после этого можно
Label1.Caption:= s;
//впрочем можно и без этого, какая разница откуда копировать, разница где это предполагается использовать...
Label1.Caption:= a;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
a: array [0..MAX_PATH] of Char;
begin
GetSystemDirectory(a, MAX_PATH);
Label1.Caption:= a;
end;
используя массив (говорилось ещё в [1])
Anatoly Podgoretsky (2006-11-05 15:32:00) [25]> Ketmar (05.11.2006 15:24:18) [18]
Смотри последний пример, ну не надо же полностью все писать, кое что надо
оставить и автору, у нас тут форум не по написанию программ, а для общения и
советов.
Anatoly Podgoretsky (2006-11-05 15:31:00) [26]> Max_2006 (05.11.2006 15:20:17) [17]
Сделай придение к PChar - PChar(S) и выдели место для хранения результата
как SetLength(S, MAX_PATH)
Полный код будет выглядеть так
SetLength(S, MAX_PATH);
N := GetSystemDirectory(S, MAX_PATH);
SetLength(S, N);
Добавить обработку ошибок
Anatoly Podgoretsky (2006-11-05 15:27:00) [27]> Max_2006 (05.11.2006 15:18:16) [16]
> а что быстрее будет работать S := PChar(S); или SetLength(S, N);?
Естественно второе, поскольку не требуется сканировать строку на предмет
определения ее длины
> как же то что перед тем как строка string чтобы передалась в API ?
> функцию, она всеравно переводится в PChar?
Использовать функцию PChar, она проверяет не пустая ли строка и если не
пустая, то возращает указатель как есть, а если пустая, то возращает
указатель на предопределенную пустую строку, доступ к которой RO
Ketmar (2006-11-05 15:24:00) [28]>[14] Anatoly Podgoretsky(c) 5-Nov-2006, 14:56
>А тепеть тоже самое, но со String
э-э-э... скажи, что ты пошутил, а? не мог же ты серьёзно такой бред родить.
Max_2006 (2006-11-05 15:20:00) [29]А еще в этом примере, Anatoly Podgoretsky © (05.11.06 14:56) [14] на строке N := GetSystemDirectory(S, MAX_PATH); ошибка при компиляции: [Pascal Error] Unit1.pas(32): E2010 Incompatible types: 'string' and 'PAnsiChar'
Max_2006 (2006-11-05 15:18:00) [30]Anatoly Podgoretsky:
> // если есть желание обрезать то S := PChar(S);// или
> воспользоваться результатом работы функции SetLength(S,
> N);
а что быстрее будет работать S := PChar(S); или SetLength(S, N);?
> А быстродействие с PChar хуже, функциям приходится искать
> конец строки методом сканирования. Кроме того как правило
> надо еще и выделять и освобождать память, при том в куче.
А как же то что перед тем как строка string чтобы передалась в API функцию, она всеравно переводится в PChar?
Anatoly Podgoretsky (2006-11-05 14:57:00) [31]> palva (05.11.2006 14:22:07) [7]
Мой код короче - одна или две строки, если с обрезанием.
Anatoly Podgoretsky (2006-11-05 14:56:00) [32]> Leonid Troyanovsky (05.11.2006 14:03:05) [5]
А тепеть тоже самое, но со String
var
S: string;
N: Integer;
begin
N := GetSystemDirectory(S, MAX_PATH);
// если есть желание обрезать то
S := PChar(S);
// или воспользоваться результатом работы функции
SetLength(S, N);
end;
Anatoly Podgoretsky (2006-11-05 14:52:00) [33]> sniknik (05.11.2006 14:02:04) [4]
> ну ладно, пусть решили что оставить размер как есть эффективнее (не будем
> память экономить, переключимся на быстродействие),
А быстродействие с PChar хуже, функциям приходится искать конец строки
методом сканирования. Кроме того как правило надо еще и выделять и
освобождать память, при том в куче.
Anatoly Podgoretsky (2006-11-05 14:49:00) [34]> Dmitry_177 (05.11.2006 13:12:02) [2]
> хотел бы сделать приложение максимально эффективное
А достигаешь совсем противоположного.
Anatoly Podgoretsky (2006-11-05 14:49:00) [35]> sniknik (05.11.2006 13:05:01) [1]
> интересно, а откуда берутся, в примерно в одно время, кучи однотипных
> вопросов, причём с примерно одинаковым незнанием тех же основ разными(???)
> авторами
А ты не знаешь? К сожалению в наших учебных заведения экзамены,
самостоятельные! работы проходят в одно и тоже время, а все предыдущее время
проводилось в других местах.
Anatoly Podgoretsky (2006-11-05 14:47:00) [36]> Max_2006 (05.11.2006 12:38:00) [0]
Ее на надо образать, это лишнее, у нее есть естественный ограничитель.
А за что так ненавидишь тип String, вот там твое пожелание будет
естественным образом реализовано.
S := P;
Правда и P тут совсем лишнее. И заботиться об удалении не надо, и ошибок
будет на порядок меньше. В справке четко сказано, что тип String полностью
совместим с PCharи поэтому твое желание выглядит как то очень странно, если
не сказать больше.
KilkennyCat (2006-11-05 14:37:00) [37]> [4] sniknik © (05.11.06 14:02)
> и самое главное, все это, то что ты делаешь думая что оптимизация...,
> на самом деле называется "экономия на спичках", за счет
> указателей, сдвигов, самостоятельных учетов блоков памяти,
> выиграть можно не более 5% скорости (испортить и сделать
> медленнее гораздо проще и вероятнее) чем если следовать
> стандартам (где уже все продумано), а вот на логике приложения
> можно выиграть на порядки (200%/1000%), если решать задачу
> а не проблемы выбранного пути решения... но почему то о
> ней не задумываются.
Абсолютно верно. Причем это ведь настолько часто разжевывается, в нормальных книжках, особенно разжевывают "игроделы", но воз и ныне там... Лезут в дебри, оптимизируют оптимизированное... лучше бы уж просто на приятный интерфейс время тратили :)
Leonid Troyanovsky (2006-11-05 14:24:00) [38]
> Max_2006 (05.11.06 14:21) [6]
> Leonid Troyanovsky, Я имел ввиду на API, не используя модуль
> SysUtils. А функции StrAlloc и StrCopy какраз от туда...
GetMem, Move
--
Regards, LVT.
palva (2006-11-05 14:22:00) [39]Можно так:
{$APPTYPE CONSOLE}
uses Windows;
var
s: String;
len: Integer;
begin
len := GetSystemDirectory(nil, 0);
WriteLn(len); // 18
SetLength(s, len - 1);
GetSystemDirectory(PChar(s), len);
WriteLn(s); // C:\WINNT\system32
end.
Max_2006 (2006-11-05 14:21:00) [40]Leonid Troyanovsky, Я имел ввиду на API, не используя модуль SysUtils. А функции StrAlloc и StrCopy какраз от туда...