Конференция "Прочее" » Разбор кода подсчета трафика
 
  • ketmar © (08.07.08 15:54) [40]
    >[39] AlexKniga © (2008-07-08 15:52:00)
    а, ну да. tnx. провтыкал, должен был сам адрес дать. %-)

    ---
    Understanding is not required. Only obedience.
  • wl © (08.07.08 15:55) [41]

    > ketmar ©   (08.07.08 15:47) [38]

    а код похоже на чистом С, там вроде не было new
  • ob_kun (08.07.08 15:58) [42]
    Еще один вопрос: насколько я разобрался в коде, там идет показание параметров соединений только один раз. Стоит так и оставить таймер для обновления данных?
  • ketmar © (08.07.08 15:58) [43]
    >[41] wl © (2008-07-08 15:55:00)
    >а код похоже на чистом С

    неа. цпп. в чистом C можно void * присваивать любому указателю, а цпп это запрещает. отсюда там приведение типа.

    ---
    Do what thou wilt shall be the whole of the Law.
  • ketmar © (08.07.08 15:59) [44]
    >[42] ob_kun (2008-07-08 15:58:00)
    а это тебе видней. там же не готовая софтина, там просто пример правильного использования API.

    ---
    All Your Base Are Belong to Us
  • ob_kun (08.07.08 16:34) [45]
    ketmar, а как понять вашу фразу про "локальную переменную"? Все переменные, использующиеся в var внутри Timer1Timer, перенести в private у формы?
  • ketmar © (08.07.08 16:52) [46]
    >[45] ob_kun (2008-07-08 16:34:00)
    зачем же все? только буфер с результатом.

    зыж я тут один, лучше на ты.

    ---
    All Your Base Are Belong to Us
  • ketmar © (08.07.08 16:53) [47]
    >[45] ob_kun (2008-07-08 16:34:00)
    точнее, буфер и его размер.

    ---
    Understanding is not required. Only obedience.
  • ob_kun (08.07.08 16:57) [48]
    То, что обозначено как pIfTable и dwSize в указанном тобой примере?
  • ketmar © (08.07.08 17:06) [49]
    >[48] ob_kun (2008-07-08 16:57:00)
    угу. с достаточно большой вероятностью они после первого «устаканивания» размера изменяться не будут, зачем каждый раз создавать и уничтожать буфер? это имеет смысл, если функция вызывается один раз, а если по таймеру — никакого смысла нет. вообще, вызов GetIfTable() вместе с "устаканиванием" есть смысл вытащить в отдельный метод, нечего обработчик захламлять деталями. да и обновление списка тоже. пусть в обработчике останется нечто типа:

    GetIfInfo();
    UpdateIfList();


    и хватит.

    зыж pdwSize (какой, всё-таки, идиот их научил понимать венгерскую нотацию так…)

    ---
    Understanding is not required. Only obedience.
  • ob_kun (08.07.08 17:08) [50]
    Извини, я написал простой код, он чисто показать, как я понял переписывание функции, можешь посмотреть, если сюда напишу?
  • ob_kun (08.07.08 17:12) [51]
    procedure TForm2.tmrTimer(Sender: TObject);
    var
    dwSize : DWORD;
    dwRetVal : DWORD;
    i, j : Integer;
    pIfTable : PMibIfTable;
    pIfRow :  PMibIfRow; // pIfTable и dwSize вынесу позже в private
    begin
     New(pIfTable);
     if pIfTable = Nil then exit;
     dwSize := sizeOf(TMibIfTable);
     if GetIfTable(pIfTable, @dwSize, False) = ERROR_INSUFFICIENT_BUFFER then
     begin
       Dispose(pIfTable);
       GetMem(pIfTable, dwSize);  // иначе будет как-то глупо вновь писать New(pIfTable)
       if pIfTable = Nil then exit;
     end;
     dwRetVal := GetIfTable(pIfTable, @dwSize, False);
     if dwRetVal <> NO_ERROR then exit;
       for i := 0  to pIfTable.dwNumEntries-1 do
       begin
         if not Flag then begin
           with lv.Items.Add do
           begin
             Caption := Trim(IntToStr(pIfTable.Table[i].dwIndex)+' '+pIfTable.Table[i].bDescr);
             // а тут дальнейшее заполнение
           end;
         end;
       end;
       if not Flag then Flag := True;
    end;

  • ketmar © (08.07.08 17:12) [52]
    >[50] ob_kun (2008-07-08 17:08:00)
    посмотреть могу. и не только я. %-) я тут далеко не самый умный.

    ---
    Do what thou wilt shall be the whole of the Law.
  • ob_kun (08.07.08 17:16) [53]
    Ну вот, собственно, мой убогий сорец ;)
  • ketmar © (08.07.08 17:17) [54]
    >[51] ob_kun (2008-07-08 17:12:00)
    не совсем так. а точнее, совсем не так. ну, проверки пока опустим, фиг с ними. ты про обновление списка не понял.

    смотри, после первого вызова у тебя уже есть заполненый список. при повторном вызове надо (грубо, можно умнее, но это сейчас не важно) пройтись по списку и проверить, нет ли уже такого элемента в списке. почти наверняка он есть — вот тут достаточно обновить элемент, а не создавать новый. в первом варианте список чистился и заново заполнялся каждый раз — вот это лишнее. достаточно проверить, если ли уже в списке такой элемент и обновить только нужные поля. а вот если нет — тогда создать. а если остались элементы, которые на данном шаге не обновлялись — то их выкинуть.

    ну, и BeginUpdate()/EndUpdate() нелохо бы, в виде той же косметики.

    ---
    Do what thou wilt shall be the whole of the Law.
  • ketmar © (08.07.08 17:20) [55]
    >[51] ob_kun (2008-07-08 17:12:00)
    т.е. "в лоб" нечто вроде:

    foreach ifItem in pIfTable do
     if IsItemInList(ifItem) then ОбновитьЭлементИОтметитьКакОбновлённый();
     else ДобавитьЭлементИОтметитьКакОбновлённый();
     end;
    end;
    ...
    foreach liItem in list do
     if НеОтмеченКакОбновлённый(liItem) then УдлалитьИзСписка(liItem); end;
    end;


    думаю, псевдокод понятен? %-)

    ---
    Do what thou wilt shall be the whole of the Law.
  • ob_kun (08.07.08 17:23) [56]
    Да нет, это как раз я понял. Я уже дописал вариант, но он падает, взгляни: (SubItems[3] - это скорость)


    procedure TForm2.tmrTimer(Sender: TObject);
    var
    dwSize : DWORD;
    dwRetVal : DWORD;
    i, j : Integer;
    pIfTable : PMibIfTable;
    pIfRow :  PMibIfRow; // pIfTable и dwSize вынесу позже в private
    begin
     New(pIfTable);
     if pIfTable = Nil then exit;
     dwSize := sizeOf(TMibIfTable);
     if GetIfTable(pIfTable, @dwSize, False) = ERROR_INSUFFICIENT_BUFFER then
     begin
       Dispose(pIfTable);
       GetMem(pIfTable, dwSize);  // иначе будет как-то глупо вновь писать New(pIfTable)
       if pIfTable = Nil then exit;
     end;
     dwRetVal := GetIfTable(pIfTable, @dwSize, False);
     if dwRetVal <> NO_ERROR then exit;
       for i := 0  to pIfTable.dwNumEntries-1 do
       begin
         if not Flag then begin
           with lv.Items.Add do
           begin
             Caption := Trim(pIfTable.Table[i].bDescr);
             // а тут дальнейшее заполнение
             SubItems.Add('');
             SubItems.Add('');
             SubItems.Add(SpeedToStr(pIfTable.Table[i].dwSpeed));
           end;
         end
         else
         begin
           for j := 0 to pIfTable.dwNumEntries-1 do
           begin
             if Trim(pIfTable.Table[j].bDescr)=lv.Items[j].Caption then
             begin
               lv.Items[j].SubItems[3] := SpeedToStr(pIfTable.Table[i].dwSpeed);
               exit;
             end;
           end;
         end;
       end;
       if not Flag then Flag := True;
    end;

  • ob_kun (08.07.08 17:30) [57]
    Подправил ошибки, но все равно бага.... правлю...
  • ketmar © (08.07.08 17:31) [58]
    >[56] ob_kun (2008-07-08 17:23:00)
    зачем тебе Flag? процесс заполнения/изменения списка абсолютно не зависит от того, вызвали ли его в первый раз или в сотый. в первый раз ветка «если ли уже всписке» просто всегда будет возвращать false — и что? пусть себе. алгоритм не меняется.

    алсо, с чего ты решил, что pIfTable.dwNumEntries и lv.Items.Count равны? это никак не гарантируется, нет такого обещания.

    почитай мой псевдокод внимательней, он совсем не то, что ты написал.

    ---
    All Your Base Are Belong to Us
  • ketmar © (08.07.08 17:32) [59]
    >[57] ob_kun (2008-07-08 17:30:00)
    бага для начала в логике.

    ---
    Understanding is not required. Only obedience.
 
Конференция "Прочее" » Разбор кода подсчета трафика
Есть новые Нет новых   [134439   +49][b:0][p:0.003]