![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
SNMP и Delphi 2009 - непонятки с указателем [WinXP]
tytus © (2009-08-13 12:07:00)Добрый день мастера.
Есть файл Snmp_Api, в нем записи:
PAsnOctetString = ^TAsnOctetString;
TAsnOctetString = record
stream: PByte;
length: UINT;
dynam: BOOL;
end;
PAsnAny = ^TAsnAny;
TAsnAny = record
asnType: BYTE;
caseInteger 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 запросов
procedureTMainFm.PrintVarBind(const VarBind: TSnmpVarBind);
объявлена переменная
var
P: PByte;
затем, втеле процедуры, определяем тип ответа:
withVarBind.value do
caseasnType of
...
ASN_OCTETSTRING:
begin
A[2] := 'Octet String';
if str.length > 0 then
begin
IsAscii := True;
P := str.stream;
fori := 0 tostr.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"..
Подскажите, как с этим бороться.
tytus (2009-08-17 16:51:00) [1]Вот нашел решение:
{$Align 4}
tytus (2009-08-14 16:14:00) [2]> Дмитрий Белькевич (14.08.09 14:12) [12]
так почему-же в Д2009 не работает сей код?
Неверно определяется указатель на данные вVarBindList.
Дмитрий Белькевич (2009-08-14 14:12:00) [3]
> Намутили embarcadero со своим юникодом IDE и всего прочего.
> .. но все равно, хочеться разобраться, в чем тут дело...
> Какие еще есть варианты?
Намутили, если уж на то пошло, еще Майкрософт. А Эмбаркадеро проделало огромадную работу, что бы к этому всему 'счастью' приспособиться. Имейте уважение.
tytus (2009-08-14 10:44:00) [4]> Сергей М. © (14.08.09 10:16) [10]
Вполне можно было предположить, что я правильно оперировал типами строк... и никоим образом не хотел вас обмануть.
Намутили embarcadero со своим юникодом IDE и всего прочего...
но все равно, хочеться разобраться, в чем тут дело...
Какие еще есть варианты?
Сергей М. (2009-08-14 10:16:00) [5]Я же спросил:
> Некая переменная типа string .. ?
Ты отвечаешь:
> именно так
А теперь говоришь, что не именно и не так:
> var
> sOID: AnsiString;
tytus (2009-08-14 10:08:00) [6]> Сергей М. © (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-13 20:47:00) [7]
> tytus (13.08.09 17:47) [7]
> именно так
Ну а раз именно так, то первым параметром ты передал указатель на строку в юникоде, хотя ф-ция ожидает ansi-строку
tytus (2009-08-13 17:47:00) [8]> Сергей М. © (13.08.09 17:18) [5]
именно так.
> Сергей М. © (13.08.09 17:21) [6]
анализ есть, не писал для краткости...
try
...
if notSnmpMgrStrToOid(PAnsiChar(sOID), @OID) then
begin
RaiseException.CreateFmt('Invalid Oids, ''%s'', specified.', [sOID]);
end;
...
finally
SnmpMgrClose(Session);
end;
Сергей М. (2009-08-13 17:21:00) [9]И какого лешего у тебя отсутствует анализ результата. возвращаемого функциейSnmpMgrStrToOid() ? Хотя бы в целях отладки ?
Сергей М. (2009-08-13 17:18:00) [10]
> sOID - текст эдита
Что значит "текст эдита" ?
Некая переменная типа string, в которую ты ранее сохранил значение св-ва Edit.Text ? Или что ?
tytus (2009-08-13 15:33:00) [11]> 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 - ошибка...
functionSnmpMgrRequest(session: PSnmpMgrSession; requestType: Byte; variableBindings: PSnmpVarBindList;
errorStatus: PAsnInteger32; errorIndex: PAsnInteger32): SNMPAPI; stdcall;
functionSnmpMgrRequest; external 'mgmtapi.dll' name 'SnmpMgrRequest';
DVM (2009-08-13 15:07:00) [12]
> tytus
вероятно у тебя какое то несоответствие между значением str.length и реальной длиной str.stream. Случайно из строки типа string ничего туда не переносилось?
tytus (2009-08-13 12:34:00) [13]>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 12:21:00) [14]что такое str ?