Работа с описателями

Обсуждение статей, опубликованных на сайте.
gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Работа с описателями

Сообщение gaidar » 20.05.2006 (Сб) 20:01

Twister
Работа с описателями


http://www.vbstreets.ru/VB/Articles/66343.aspx
The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

Amed
Алфизик
Алфизик
 
Сообщения: 5346
Зарегистрирован: 09.03.2003 (Вс) 9:26

Сообщение Amed » 20.05.2006 (Сб) 20:04

Картинки не грузятся. Совсем.

gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Сообщение gaidar » 20.05.2006 (Сб) 20:11

Какие картинки?
The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 20.05.2006 (Сб) 21:44

Ещё вопрос к Twister-у, а также GSerg-у и многим другим, от которых я видел такой же код.

Код: Выделить всё
Public Function GetStrFromPtrW(lpszW As Long) As String
Dim sRtn As String
sRtn = String$(lstrlenW(ByVal lpszW) * 2, 0)
Call WideCharToMultiByte(CP_ACP, 0, ByVal lpszW, -1, ByVal sRtn, Len(sRtn), _
                                                                       0, 0)
GetStrFromPtrW = GetStrFromBufferA(sRtn)
End Function

Private Function GetStrFromBufferA(sz As String) As String
If InStr(sz, vbNullChar) Then
    GetStrFromBufferA = Left$(sz, InStr(sz, vbNullChar) - 1)
Else
    GetStrFromBufferA = sz
End If
End Function


Почему бы не использовать вместо этого чуда мысли один вызов SysAllocString?
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 21.05.2006 (Вс) 15:40

GSerg такого точно написать не мог. Он LPWSRT в CopyMemory отправляет, как впрочем, и LPSTR. Ибо, в итоге это один фиг получается...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 21.05.2006 (Вс) 15:52

А зачем вообще GSerg, так же как Twister и остальные, самостоятельно изобретает замену давно существующей функции?
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 21.05.2006 (Вс) 17:28

Вопрос этот сложен и многогранен.

Как известно, VB осуществляет конвертирование строк сами знает откуда сами знаете куда при вызове API и обратное конвертирование при возврате из API.
Если API объявлена As String, то VB, разумеется, сконвертирует результат сами знаете куда, и его будет мало волновать, следует ли делать это.

Простой пример.
Согласно документации, SysAllocString принимает параметром указатель на юникодовую строку, и возвращает BSTR с той же строкой. Вызываем:
Код: Выделить всё
Option Explicit

Private Declare Function SysAllocString Lib "oleaut32.dll" (ByVal pOlechar As Long) As String

Private Sub Form_Load()
  Dim pattern As String, result As String
 
  pattern = "Проверка"
  result = SysAllocString(StrPtr(pattern))
 
  MsgBox result
  MsgBox StrConv(result, vbFromUnicode)
End Sub


Комментарии излишни. Нафига нам позволять VB сначала конвертировать результат из ANSI в юникод, а потом ручками конвертировать обратно, в то время как мы можем вызвать CopyMemory, и сократить число конвертирований с 2 до 0?

Сей метод, с SysAllocString, актуален разве что когда на самом деле строка вовсе не в юникоде. Тогда SysAllocString тупо её скопирует, VB развернёт результат в юникод при возврате из функции и всё будет нормально - НО для этого требуется, чтобы та самая ANSI-строка заканчивалась не одним, а двумя vbNullChar, иначе есть большой риск огрести сами знаете что.

Фыфот?
Нафиг нам не нужна SysAllocString.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Сообщение gaidar » 21.05.2006 (Вс) 18:21

GSerg, а напиши-ка по этому поводу пухлую статью, а? Поскольку это многим интересно, но мало кто об этом знает и терпения копать тоже мало у кого хватает.
The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 21.05.2006 (Вс) 20:15

2GSerg:

1) данный метод тобой рекомендовался и для ANSI-строк, где конвертацию -- при использовании CopyMemory -- всё равно приходится выполнять явно.

2) для тех, у кого в конце строк один vbNullChar, а не два, есть SysAllocStringByteLen.

3) а сколько преобразований в коде Twister-а, интересно, если он вызывает WideCharToMultiByte для конвертации строки из Юникода в Юникод? ;-)
Мне почему-то кажется, что те же два, которые мы получаем вызовом SysAllocString в лоб.

4) для продвинутых всегда есть возможность объявить SysAllocString в TLB, и излишняя конвертация не будет выполняться. Более того, по моему опыту, в продвинутых программах без TLB всё равно не обойтись, и добавить в неё одно объявление -- не заморочно.
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 22.05.2006 (Пн) 8:49

1) Ага. Только там она одна, конвертация :)

2) А про неё ты выше не упоминал :)

3) Дык причём тут код Твистера? Раз уж ты включил меня в число опрашиваемых по данному вопросу и после того, как я объяснил, что я так не делаю, а пользуюсь исключительно CopyMemory, так и рассматриваем только мою CopyMemory и твою SysAllocString :)

4) Да - но опять же, ты не упоминал об этом выше :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.05.2006 (Пн) 10:02

Нет, мой изначальный вопрос был шире: "зачем писать своё, когда уже есть готовое".

Осталось дождаться комментариев Twister-а.
Изображение

gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Сообщение gaidar » 22.05.2006 (Пн) 10:37

GSerg и Tyomitch, как дойдете до истины, пишите статью! :)
The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 22.05.2006 (Пн) 19:31

Комментарии Twister-а:
GSerg писал(а):LPWSRT в CopyMemory отправляет, как впрочем, и LPSTR
Да, мы это с GSerg-ом в АСЕ обсуждали, но что-то с первого раза у меня не вышло, поэтому решил просто воспользоваться кодом из API-Guidа. Об оптимизации конвертации строк я, честно говоря, не задумывался...
А я все практикую лечение травами...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.05.2006 (Пн) 19:39

В API-Guide чего только не понапишут... Даже про ExitProcess(GetExitCodeProcess(GetCurrentProcess))) есть.
Почему его возвели в статус эталона?
Изображение

GM
programador
programador
 
Сообщения: 1427
Зарегистрирован: 24.06.2003 (Вт) 15:56
Откуда: 194.67.52.100

Сообщение GM » 22.05.2006 (Пн) 21:08

... для продвинутых всегда есть возможность объявить SysAllocString в TLB, и излишняя конвертация не будет выполняться. Более того, по моему опыту, в продвинутых программах без TLB всё равно не обойтись, и добавить в неё одно объявление -- не заморочно.

Я когда писал свою библиотеку для быстрой работы со строками именно так и делал, достаточно было объявить строку как:
long InStrQ([in] long Start,[in] BSTR String, [in] BSTR SubString);

И VB без конвертации передавал ф-цию в мою dll'ку.
الفيجوال بيسك الرابح

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 22.05.2006 (Пн) 22:01

tyomitch писал(а):В API-Guide чего только не понапишут... Даже про ExitProcess(GetExitCodeProcess(GetCurrentProcess))) есть.
Почему его возвели в статус эталона?
О чем ты? Какого эталона? Просто я использовал то, что первое попалось под руку.
А я все практикую лечение травами...

gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Сообщение gaidar » 22.05.2006 (Пн) 23:35

Примеры в API Guide писали люди еще в то время, когда только учились программировать, так что глюков там немерено.
The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 23.05.2006 (Вт) 9:10

Маленькая поправочка к статье:
Twister писал(а):Нам нужно лишь найти нужный описатель (сравнивая ProcessId в структуре SYSTEM_HANDLE_INFORMATION c PID-ом KAV-а)
Ошибочка вышла - ночью по запарке совсем не то написал. ProcessId в структуре SYSTEM_HANDLE_INFORMATION нужно сравнивать с PID-ом csrss и если они равны, то опрашивать описатель с помощью ZwQueryInformationProcess. Если в полученном буфере (тип PROCESS_BASIC_INFORMATION) поле UniqueProcessId равно PID-у KAV, то значит нашли, можно копировать...
А я все практикую лечение травами...

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 23.05.2006 (Вт) 9:12

Ох, тут нельзя редактировать посты... Тогда добавлю новый.

Гайдар, а нельзя ли этот момент прямо в статье поправить? А то даже стыдно как-то... :oops:
А я все практикую лечение травами...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 23.05.2006 (Вт) 9:26

Twister, тогда и GetStrFromPtrW заодно поправь ;-)
Код тебе GSerg уже дал.
Изображение

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 23.05.2006 (Вт) 9:30

Ну насчет поправок - к Гайдару.
Хотя я ж говорю - цель оптимизировать ВСЕ я не ставил... По идее нужно уточнить работу с потоками.
А я все практикую лечение травами...

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 26.05.2006 (Пт) 20:31

Вот тут лежит поправленный вариант...
http://twister-kz.narod.ru/Articles/handles_vb.html
А я все практикую лечение травами...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 26.05.2006 (Пт) 21:03

tyomitch писал(а):Twister, тогда и GetStrFromPtrW заодно поправь ;-)
Код тебе GSerg уже дал.
Изображение

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 26.05.2006 (Пт) 21:05

Twister писал(а):цель оптимизировать ВСЕ я не ставил... По идее нужно еще уточнить работу с потоками.
А я все практикую лечение травами...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 26.05.2006 (Пт) 21:29

Тебе дали готовый код. Тебе тяжело вставить одну строчку вместо двух процедур?
Изображение

gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Сообщение gaidar » 26.05.2006 (Пт) 23:43

Жду правленой статьи на mail.

Кстати, на VBStreets мы обычно эксклюзивно статьи публикуем...
The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 31.05.2006 (Ср) 18:48

tyomitch писал(а):Тебе дали готовый код. Тебе тяжело вставить одну строчку вместо двух процедур?
Да дело не в готовом коде. Дело в том, что статья моя о хэндлах, а не о конвертации строк. Но... Поправочку я внес и хочу сказать спасибо за подсказку. Нормальная версия тут. На мыло к Гайдару она тоже ушла. Будем ждать...
А я все практикую лечение травами...

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 07.06.2006 (Ср) 12:54

Вижу статью gaidar поправил. Большое спасибо.
tyomitch, нормально, ты доволен? :wink:
А я все практикую лечение травами...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 07.06.2006 (Ср) 13:00

Я доволен, и пользуясь случаем, указываю gaidar-у на свою субмиссию: http://bbs.vbstreets.ru/viewtopic.php?p=6609749#6609749
Изображение

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 10.06.2006 (Сб) 1:51

gaidar писал(а):GSerg и Tyomitch, как дойдете до истины, пишите статью! :)

Подойдёт?
Изображение

След.

Вернуться в Статьи

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9

    TopList