Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.10.18;
Скачать: CL | DM;

Вниз

SNMP и Delphi 2009 - непонятки с указателем   Найти похожие ветки 

 
tytus   (2009-08-13 12:07) [0]

Добрый день мастера.
Есть файл Snmp_Api, в нем записи:

 PAsnOctetString = ^TAsnOctetString;
 TAsnOctetString = record
   stream: PByte;
   length: UINT;
   dynam: BOOL;
 end;

 PAsnAny = ^TAsnAny;
 TAsnAny = record
   asnType: BYTE;
   case Integer of      0: (number: TAsnInteger32);          { ASN_INTEGER, ASN_INTEGER32 }
     1: (unsigned32: TAsnUnsigned32);     { ASN_UNSIGNED32 }
     2: (counter64: TAsnCounter64);       { ASN_COUNTER64 }
     3: (str: TAsnOctetString);           { ASN_OCTETSTRING }
     4: (bits: TAsnBits);                 { ASN_BITS }
     5: (obj: TAsnObjectIdentifier);      { ASN_OBJECTIDENTIFIER }
     6: (sequence: TAsnSequence);         { ASN_SEQUENCE }
     7: (address: TAsnIpAddress);         { ASN_IPADDRESS }
     8: (counter: TAsnCounter32);         { ASN_COUNTER32 }
     9: (gauge: TAsnGauge32);             { ASN_GAUGE32 }
    10: (ticks: TAsnTimeticks);           { ASN_TIMETICKS }
    11: (arbitrary: TAsnOpaque);          { ASN_OPAQUE }
 end;

 TAsnObjectName = TAsnObjectIdentifier;
 TAsnObjectSyntax = TAsnAny;

 PSnmpVarBind = ^TSnmpVarBind;
 TSnmpVarBind = record
   name: TAsnObjectName;
   value: TAsnObjectSyntax;
 end;

 PSnmpVarBindList = ^TSnmpVarBindList;
 TSnmpVarBindList = record
   list: PSnmpVarBind;
   len: UINT;
 end;


В главном юните есть процедура, для получения результатов SNMP запросов
procedure TMainFm.PrintVarBind(const VarBind: TSnmpVarBind);
объявлена переменная
var
 P: PByte;


затем, втеле процедуры, определяем тип ответа:

with VarBind.value do
   case asnType of
...
     ASN_OCTETSTRING:
       begin
         A[2] := "Octet String";
         if str.length > 0 then
         begin
           IsAscii := True;
           P := str.stream;
           for i := 0 to str.length - 1 do
           begin
             if not (P^ in [0, 32..127]) then    // <-- ТУТ ОШИБКА!!!
             begin
               IsAscii := False;
               Break;
             end;
             Inc(P);
           end;
...
 end;


В Delphi 2007 этот код работает нормально, длина строки 89 (к примеру). В D2009 длина строки = 1, адрес str.stream равен $59 - вот и ошибка - "read from address $00000059"..

Подскажите, как с этим бороться.


 
DVM ©   (2009-08-13 12:21) [1]

что такое str ?


 
tytus   (2009-08-13 12:34) [2]

>DVM  (13.08.09 12:21) [1]
PAsnAny = ^TAsnAny;
TAsnAny = record
  asnType: BYTE;
  case Integer of      0: (number: TAsnInteger32);          { ASN_INTEGER, ASN_INTEGER32 }
    1: (unsigned32: TAsnUnsigned32);     { ASN_UNSIGNED32 }
    2: (counter64: TAsnCounter64);       { ASN_COUNTER64 }
    3: (str: TAsnOctetString);           { ASN_OCTETSTRING } <-- Вот ОНО - str!!!
    4: (bits: TAsnBits);                 { ASN_BITS }
    5: (obj: TAsnObjectIdentifier);      { ASN_OBJECTIDENTIFIER }
    6: (sequence: TAsnSequence);         { ASN_SEQUENCE }
    7: (address: TAsnIpAddress);         { ASN_IPADDRESS }
    8: (counter: TAsnCounter32);         { ASN_COUNTER32 }
    9: (gauge: TAsnGauge32);             { ASN_GAUGE32 }
   10: (ticks: TAsnTimeticks);           { ASN_TIMETICKS }
   11: (arbitrary: TAsnOpaque);          { ASN_OPAQUE }
end;


 
DVM ©   (2009-08-13 15:07) [3]


> tytus

вероятно у тебя какое то несоответствие между значением str.length и реальной длиной str.stream. Случайно из строки типа string ничего туда не переносилось?


 
tytus   (2009-08-13 15:33) [4]

> DVM ©   (13.08.09 15:07) [3]
да нет, ничего...
вот как отправляю запрос:
1) SnmpMgrStrToOid(PAnsiChar(sOID), @OID);где OID - TAsnObjectIdentifier, sOID - текст эдита.
2) with VarBindList do
   begin
     list :=  SnmpUtilMemAlloc(SizeOf(TSnmpVarBind));
     len := 1;
     list^.name := OID;
     list^.value.asnType := ASN_NULL;
   end;

3) RequestType := SNMP_PDU_GET;
   RetVal := SnmpMgrRequest(Session, RequestType, @VarBindList,
       @ErrorStatus, @ErrorIndex);

4) - получаем ответ
    PrintVarBind(VarBindList.list^);

Несоответствие может произойти, если компиляторы D2007 и D2009 по-разному работают.
В Д2007-ом работает, а в Д2009  - ошибка...

function SnmpMgrRequest(session: PSnmpMgrSession; requestType: Byte; variableBindings: PSnmpVarBindList;
 errorStatus: PAsnInteger32; errorIndex: PAsnInteger32): SNMPAPI; stdcall;

function SnmpMgrRequest; external  "mgmtapi.dll"  name  "SnmpMgrRequest";


 
Сергей М. ©   (2009-08-13 17:18) [5]


> sOID - текст эдита


Что значит "текст эдита" ?
Некая переменная типа string, в которую ты ранее сохранил значение св-ва Edit.Text ? Или что ?


 
Сергей М. ©   (2009-08-13 17:21) [6]

И какого лешего у тебя отсутствует анализ результата. возвращаемого функцией SnmpMgrStrToOid() ? Хотя бы в целях отладки ?


 
tytus   (2009-08-13 17:47) [7]

> Сергей М. ©   (13.08.09 17:18) [5]
именно так.
> Сергей М. ©   (13.08.09 17:21) [6]
анализ есть, не писал для краткости...
 try
...
   if not SnmpMgrStrToOid(PAnsiChar(sOID), @OID) then
   begin
     Raise Exception.CreateFmt("Invalid Oids, ""%s"", specified.", [sOID]);
   end;
...
 finally
   SnmpMgrClose(Session);
 end;


 
Сергей М. ©   (2009-08-13 20:47) [8]


> tytus   (13.08.09 17:47) [7]
> именно так


Ну а раз именно так, то первым параметром ты передал указатель на строку в юникоде, хотя ф-ция ожидает ansi-строку


 
tytus   (2009-08-14 10:08) [9]

> Сергей М. ©   (13.08.09 20:47) [8]

> первым параметром ты передал указатель на строку в юникоде

var
 sOID: AnsiString;
begin
 sOID := ".1.3.6.1.2.1.1.1.0"; <-- это разве не ANSI ???
 SnmpMgrStrToOid(PAnsiChar(sOID), @OID);


к тому же, в процедуре PrintVarBind есть функция
SnmpUtilOidToA(@VarBind.name), которая возвращает заданный OID,
следовательно, строка передается правильно.


 
Сергей М. ©   (2009-08-14 10:16) [10]

Я же спросил:

> Некая переменная типа string .. ?


Ты отвечаешь:

> именно так


А теперь говоришь, что не именно и не так:

> var
>  sOID: AnsiString;


 
tytus   (2009-08-14 10:44) [11]

> Сергей М. ©   (14.08.09 10:16) [10]
Вполне можно было предположить, что я правильно оперировал типами строк... и никоим образом не хотел вас обмануть.
Намутили embarcadero со своим юникодом IDE и всего прочего...
но все равно, хочеться разобраться, в чем тут дело...
Какие еще есть варианты?


 
Дмитрий Белькевич   (2009-08-14 14:12) [12]


> Намутили embarcadero со своим юникодом IDE и всего прочего.
> .. но все равно, хочеться разобраться, в чем тут дело...
> Какие еще есть варианты?


Намутили, если уж на то пошло, еще Майкрософт. А Эмбаркадеро проделало огромадную работу, что бы к этому всему "счастью" приспособиться. Имейте уважение.


 
tytus   (2009-08-14 16:14) [13]

> Дмитрий Белькевич   (14.08.09 14:12) [12]
так почему-же в Д2009 не работает сей код?
Неверно определяется указатель на данные в VarBindList.


 
tytus   (2009-08-17 16:51) [14]

Вот нашел решение:
{$Align 4}



Страницы: 1 вся ветка

Текущий архив: 2009.10.18;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.011 c
2-1250249797
JS2
2009-08-14 15:36
2009.10.18
asm


15-1250152317
Наиль
2009-08-13 12:31
2009.10.18
Запрет продаж MS Word


15-1250501563
ford
2009-08-17 13:32
2009.10.18
запись в реестр в ветку HKLM


1-1219665943
Still Swamp
2008-08-25 16:05
2009.10.18
Найти и заменить все строки в подстроке.


1-1219671204
dmitry_12_08_73
2008-08-25 17:33
2009.10.18
Как можно рисовать объект типа TPanel в любом месте экрана