Форум: "Начинающим";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];
ВнизРабота с PChar средствами Windows (API) Найти похожие ветки
← →
Max_2006 (2006-11-05 12:38) [0]как работать с 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 не предлагайте...
← →
sniknik © (2006-11-05 13:05) [1]> Работу со String и ShortString не предлагайте...
тогда предлагаю работать с массивом of char;...
p.s. интересно, а откуда берутся, в примерно в одно время, кучи однотипных вопросов, причём с примерно одинаковым незнанием тех же основ разными(???) авторами. и с примерно одинаковым стилем... без малейшего намёка на "зачем", только с "надо вот так" + какие то надуманные ограничения...
==================================
- мама скажи "абырхвал".
- зачем?
- ну скажи!
- нет, ты скажи что это значит и зачем.
- ну мам!
- да не буду я всякую непонятную ерунду говорить.
- ВОТ!!! и меня тогда не заставляйте английский учить!
← →
Dmitry_177 (2006-11-05 13:12) [2]Просто перед тем чтобы передать строку в API функцию, компилятов переводит ее из string в PChar или массив array of Char, на это тратится какое-то время, хотел бы сделать приложение максимально эффективное... Ну и вообще ради интереса...
← →
Dmitry_177 (2006-11-05 13:14) [3]Вопрос схожий с моим ))) Но всеравно, хотел бы получить на него ответ...)))
← →
sniknik © (2006-11-05 14:02) [4]> хотел бы сделать приложение максимально эффективное...
а как думаешь делается обрезание по SetLength? выделением нового куска памяти и копированием туда отрезанной части. это эффективно?
хотелось бы тогда получить определение эффективности, что для тебя важнее ресурсы или быстродействие, т.к. с точки зрения быстродействия эффективнее было бы раз отрезать кусок памяти и пользоваться им не перераспределяя т.к. это долгая операция (с другой стороны дельфя уже сделала эту работу за нас, ее менеджер памяти выделяет блок, а после раздаёт кусочки без запросов от системы, если не вылезти за пределы конечно...)
ну и получается ты со своим полным незнанием работы системы хочешь написать эффективнее чем борланд, обходя то что он встроил? думаешь получится?
я вот сомневаюсь.
ну ладно, пусть решили что оставить размер как есть эффективнее (не будем память экономить, переключимся на быстродействие), но в показанном куске есть подозрение используется локальная переменная(!!!) это значит что при передаче она либо потеряется либо мы ее должны будем скопировать в другую с другой областью видимости, а это эффективно?, но тем не менее по другому нельзя и получается все ранние потуги насмарку...
уффф..., ещё не начал объяснять а уже упарился... все таки вам проще книжечку/лекции взять почитать... потому как однозначных ответов нет.
и самое главное, все это, то что ты делаешь думая что оптимизация..., на самом деле называется "экономия на спичках", за счет указателей, сдвигов, самостоятельных учетов блоков памяти, выиграть можно не более 5% скорости (испортить и сделать медленнее гораздо проще и вероятнее) чем если следовать стандартам (где уже все продумано), а вот на логике приложения можно выиграть на порядки (200%/1000%), если решать задачу а не проблемы выбранного пути решения... но почему то о ней не задумываются.
← →
Leonid Troyanovsky © (2006-11-05 14:03) [5]
> Max_2006 (05.11.06 12:38)
> GetMem(p, MAX_PATH);
> GetSystemDirectory(p, MAX_PATH);
var
a: array [0..MAX_PATH] of Char;
p: PChar;
n : Longint;
..
n := GetSystemDirectory(a, MAX_PATH);
Win32Check(n <> 0);
p := StrAlloc(n);
StrCopy(p, a);
..
--
Regards, LVT.
← →
Max_2006 (2006-11-05 14:21) [6]Leonid Troyanovsky, Я имел ввиду на API, не используя модуль SysUtils. А функции StrAlloc и StrCopy какраз от туда...
← →
palva © (2006-11-05 14:22) [7]Можно так:
{$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.
← →
Leonid Troyanovsky © (2006-11-05 14:24) [8]
> Max_2006 (05.11.06 14:21) [6]
> Leonid Troyanovsky, Я имел ввиду на API, не используя модуль
> SysUtils. А функции StrAlloc и StrCopy какраз от туда...
GetMem, Move
--
Regards, LVT.
← →
KilkennyCat © (2006-11-05 14:37) [9]> [4] sniknik © (05.11.06 14:02)
> и самое главное, все это, то что ты делаешь думая что оптимизация...,
> на самом деле называется "экономия на спичках", за счет
> указателей, сдвигов, самостоятельных учетов блоков памяти,
> выиграть можно не более 5% скорости (испортить и сделать
> медленнее гораздо проще и вероятнее) чем если следовать
> стандартам (где уже все продумано), а вот на логике приложения
> можно выиграть на порядки (200%/1000%), если решать задачу
> а не проблемы выбранного пути решения... но почему то о
> ней не задумываются.
Абсолютно верно. Причем это ведь настолько часто разжевывается, в нормальных книжках, особенно разжевывают "игроделы", но воз и ныне там... Лезут в дебри, оптимизируют оптимизированное... лучше бы уж просто на приятный интерфейс время тратили :)
← →
Anatoly Podgoretsky © (2006-11-05 14:47) [10]> Max_2006 (05.11.2006 12:38:00) [0]
Ее на надо образать, это лишнее, у нее есть естественный ограничитель.
А за что так ненавидишь тип String, вот там твое пожелание будет
естественным образом реализовано.
S := P;
Правда и P тут совсем лишнее. И заботиться об удалении не надо, и ошибок
будет на порядок меньше. В справке четко сказано, что тип String полностью
совместим с PCharи поэтому твое желание выглядит как то очень странно, если
не сказать больше.
← →
Anatoly Podgoretsky © (2006-11-05 14:49) [11]> sniknik (05.11.2006 13:05:01) [1]
> интересно, а откуда берутся, в примерно в одно время, кучи однотипных
> вопросов, причём с примерно одинаковым незнанием тех же основ разными(???)
> авторами
А ты не знаешь? К сожалению в наших учебных заведения экзамены,
самостоятельные! работы проходят в одно и тоже время, а все предыдущее время
проводилось в других местах.
← →
Anatoly Podgoretsky © (2006-11-05 14:49) [12]> Dmitry_177 (05.11.2006 13:12:02) [2]
> хотел бы сделать приложение максимально эффективное
А достигаешь совсем противоположного.
← →
Anatoly Podgoretsky © (2006-11-05 14:52) [13]> sniknik (05.11.2006 14:02:04) [4]
> ну ладно, пусть решили что оставить размер как есть эффективнее (не будем
> память экономить, переключимся на быстродействие),
А быстродействие с PChar хуже, функциям приходится искать конец строки
методом сканирования. Кроме того как правило надо еще и выделять и
освобождать память, при том в куче.
← →
Anatoly Podgoretsky © (2006-11-05 14:56) [14]> 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:57) [15]> palva (05.11.2006 14:22:07) [7]
Мой код короче - одна или две строки, если с обрезанием.
← →
Max_2006 (2006-11-05 15:18) [16]Anatoly Podgoretsky:
> // если есть желание обрезать то S := PChar(S);// или
> воспользоваться результатом работы функции SetLength(S,
> N);
а что быстрее будет работать S := PChar(S); или SetLength(S, N);?
> А быстродействие с PChar хуже, функциям приходится искать
> конец строки методом сканирования. Кроме того как правило
> надо еще и выделять и освобождать память, при том в куче.
А как же то что перед тем как строка string чтобы передалась в API функцию, она всеравно переводится в PChar?
← →
Max_2006 (2006-11-05 15:20) [17]А еще в этом примере, Anatoly Podgoretsky © (05.11.06 14:56) [14] на строке N := GetSystemDirectory(S, MAX_PATH); ошибка при компиляции: [Pascal Error] Unit1.pas(32): E2010 Incompatible types: "string" and "PAnsiChar"
← →
Ketmar © (2006-11-05 15:24) [18]>[14] Anatoly Podgoretsky(c) 5-Nov-2006, 14:56
>А тепеть тоже самое, но со String
э-э-э... скажи, что ты пошутил, а? не мог же ты серьёзно такой бред родить.
← →
Anatoly Podgoretsky © (2006-11-05 15:27) [19]> Max_2006 (05.11.2006 15:18:16) [16]
> а что быстрее будет работать S := PChar(S); или SetLength(S, N);?
Естественно второе, поскольку не требуется сканировать строку на предмет
определения ее длины
> как же то что перед тем как строка string чтобы передалась в API ?
> функцию, она всеравно переводится в PChar?
Использовать функцию PChar, она проверяет не пустая ли строка и если не
пустая, то возращает указатель как есть, а если пустая, то возращает
указатель на предопределенную пустую строку, доступ к которой RO
← →
Anatoly Podgoretsky © (2006-11-05 15:31) [20]> 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:32) [21]> Ketmar (05.11.2006 15:24:18) [18]
Смотри последний пример, ну не надо же полностью все писать, кое что надо
оставить и автору, у нас тут форум не по написанию программ, а для общения и
советов.
← →
sniknik © (2006-11-05 15:40) [22]> а что быстрее будет работать 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])
← →
Max_2006 (2006-11-05 15:40) [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);
← →
Ketmar © (2006-11-05 15:46) [24]>[21] Anatoly Podgoretsky(c) 5-Nov-2006, 15:32
>не надо же полностью все писать, кое что надо
>оставить и автору
так это ж раздел "надмозги". тут неписаными правилами думать воспрещается. равно как и читать справку/книги. а ты издеваешься...
← →
Anatoly Podgoretsky © (2006-11-05 15:50) [25]> Max_2006 (05.11.2006 15:40:23) [23]
Опять забыл приведение сделать, а ты сам не можешь догадаться? Тогда не
стоит программировать.
← →
Max_2006 (2006-11-05 16:09) [26]N := GetSystemDirectory(PChar(S), MAX_PATH); так? Я просто где-то видел что @S[1] так лучше, или это не так?
← →
Anatoly Podgoretsky © (2006-11-05 16:20) [27]> Max_2006 (05.11.2006 16:09:26) [26]
Так и это ты должен был понять из сообщения об ошибке.
А лучше или нет - читай обсуждения, их тут два по этой теме.
Понять ты должен сам, тогда навечно, по крайней мере до смены парадигмы.
← →
Max_2006 (2006-11-05 17:03) [28]Я просто хотел научиться писать программы на одном API, а так как там PChar то его и использовать без использования string, чтобы не тратилось время на перевод string в PChar...
← →
Anatoly Podgoretsky © (2006-11-05 17:09) [29]> Max_2006 (05.11.2006 17:03:28) [28]
string полностью совместим с PChar, имеет дополнительные
средства, управляющие его живучестью, уменьшае количество
ошибок, начинающим очень сложно работать с указателями,
с динамическим выделением памяти. Нет ни каких оснований
не использовать. Не хочешь тратить время на приведение, п
отеряешь время и память на работу с динамическим выделени
ем, при том потеряешь больше и ничего не приобретешь.
← →
Max_2006 (2006-11-05 17:37) [30]а как тогда работают в C++ с WinAPI? Там же нету string.. Если только в MFC на сколько я знаю CString (как-то так называется)... а если без MFC(на одном WinAPI), как они используют строки? Судя из цитаты:
> Не хочешь тратить время на приведение, потеряешь время и
> память на работу с динамическим выделением, при том потеряешь
> больше и ничего не приобретешь.
получается так что приложение написанное с использованием string быстрее работает чем с PChar? Т.е. быстрее чем приложение написанное на C++???
← →
Anatoly Podgoretsky © (2006-11-05 17:41) [31]Не всегда, но в основном, поскольку оно обладает информацией о размере, а для PChar такой информации нет. А они с ним и работают.
А что тебя так удивляет, что С++ обладает каким то тайным знанием, там даже цикла FOR нет, под его именем идет цикл WHILE. Так же нет массивово в чистом виде, это замаскированый указатель.
И все что касается циклов и строк как правило работает медлеенне.
Ты не читай заверения маркетологов от С++
← →
Max_2006 (2006-11-05 17:50) [32]Я тут еще так подумал, может string передавать в функцию требующая PChar так: Pointer(str)? или всеже лучше PChar(str)?
← →
Anatoly Podgoretsky © (2006-11-05 17:57) [33]> Max_2006 (05.11.2006 17:50:32) [32]
Ну и прикинь, что у тебя получится для пустой строки.
Не надо фантазировать, делай правильно, кроме тех случаев когда ты точно
знаешь зачем ты это Pointer(str) делаешь
← →
Max_2006 (2006-11-05 18:10) [34]Все же я не очень понимаю чем string выигрывает по скорости массив array [0..MAX_PATH] of Char, если выполнять с массивом какиенибудь действия то его придется копировать в новую память и т.д. А как тогда устроен string, я понимаю что по сути дела это только указатель, но а если строка все больше и больше становится, растет так сказать, то по идее память должна как-то динамически увеличиваться или как? Если динамически то на это тоже не мало времени тратится...
← →
Ketmar © (2006-11-05 18:22) [35]>[34] Max_2006 5-Nov-2006, 18:10
один фиг.
← →
sniknik © (2006-11-05 18:24) [36]> Т.е. быстрее чем приложение написанное на C++???
очень часто да быстрее, и намного (очень намного). имею под боком трех С-шников, есть прецеденты.
> Все же я не очень понимаю чем string выигрывает по скорости массив array [0..MAX_PATH] of Char
массиву ничем, для доступа, для копирования - не придётся узнавать размер строки, копирование можно сделать одной ассемблерной командой, в случае массива (вернее z терминированной строки) чтобы узнать размер придётся ее сканировать, или если делать условие на конечный 0 прям в копировании то все одно придётся делать циклом, кучей команд переноса и проверкой в цикле на 0... одна команда на все копирование 2 такта (примерно естественно), против кучи на каждый перенесённый байт и проверку, на все те же 2 такта... на каждую команду... считай. а лучше читай, найди чего нибудь для начинающих и просто выучи наизусть (по другому видно не доходит).
← →
Leonid Troyanovsky © (2006-11-05 18:34) [37]
> Max_2006 (05.11.06 17:50) [32]
> Я тут еще так подумал, может string передавать в функцию
> требующая PChar так: Pointer(str)? или всеже лучше PChar(str)?
From Delphi help: Long string types:
It is also possible to typecast a long string to an untyped pointer, using the
syntax Pointer(S), where S is a long string expression. A Pointer typecast
returns the address of the first character of the long string value. Unlike a PChar
typecast, a Pointer typecast returns nil if the string expression is empty.
--
Regards, LVT.
← →
Anatoly Podgoretsky © (2006-11-05 20:10) [38]> Max_2006 (05.11.2006 18:10:34) [34]
Никаких копирований ВинАПИ не делает.
← →
Max_2006 (2006-11-05 22:23) [39]
> Никаких копирований ВинАПИ не делает.
А я вообще про строку имел ввиду...
← →
Max_2006 (2006-11-05 22:45) [40]А если нужно расширить массив? т.е. есть массив array [0..20] of Char и он весь занят и его надо расширить, то всеравно надо создавать новый и делать move?
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.039 c