-
Добрый день мастера. Есть файл 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);
1: (unsigned32: TAsnUnsigned32);
2: (counter64: TAsnCounter64);
3: (str: TAsnOctetString);
4: (bits: TAsnBits);
5: (obj: TAsnObjectIdentifier);
6: (sequence: TAsnSequence);
7: (address: TAsnIpAddress);
8: (counter: TAsnCounter32);
9: (gauge: TAsnGauge32);
10: (ticks: TAsnTimeticks);
11: (arbitrary: TAsnOpaque);
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".. Подскажите, как с этим бороться.
-
что такое str ?
-
>DVM (13.08.09 12:21) [1] PAsnAny = ^TAsnAny;
TAsnAny = record
asnType: BYTE;
case Integer of 0: (number: TAsnInteger32);
1: (unsigned32: TAsnUnsigned32);
2: (counter64: TAsnCounter64);
3: (str: TAsnOctetString); <-- Вот ОНО - str!!!
4: (bits: TAsnBits);
5: (obj: TAsnObjectIdentifier);
6: (sequence: TAsnSequence);
7: (address: TAsnIpAddress);
8: (counter: TAsnCounter32);
9: (gauge: TAsnGauge32);
10: (ticks: TAsnTimeticks);
11: (arbitrary: TAsnOpaque);
end;
-
> tytus
вероятно у тебя какое то несоответствие между значением str.length и реальной длиной str.stream. Случайно из строки типа string ничего туда не переносилось?
-
> 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';
-
> sOID - текст эдита
Что значит "текст эдита" ? Некая переменная типа string, в которую ты ранее сохранил значение св-ва Edit.Text ? Или что ?
-
И какого лешего у тебя отсутствует анализ результата. возвращаемого функцией SnmpMgrStrToOid() ? Хотя бы в целях отладки ?
-
> Сергей М. © (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;
-
> tytus (13.08.09 17:47) [7] > именно так
Ну а раз именно так, то первым параметром ты передал указатель на строку в юникоде, хотя ф-ция ожидает ansi-строку
-
> Сергей М. © (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, следовательно, строка передается правильно.
-
Я же спросил:
> Некая переменная типа string .. ?
Ты отвечаешь:
> именно так
А теперь говоришь, что не именно и не так:
> var > sOID: AnsiString;
-
> Сергей М. © (14.08.09 10:16) [10] Вполне можно было предположить, что я правильно оперировал типами строк... и никоим образом не хотел вас обмануть. Намутили embarcadero со своим юникодом IDE и всего прочего... но все равно, хочеться разобраться, в чем тут дело... Какие еще есть варианты?
-
> Намутили embarcadero со своим юникодом IDE и всего прочего. > .. но все равно, хочеться разобраться, в чем тут дело... > Какие еще есть варианты?
Намутили, если уж на то пошло, еще Майкрософт. А Эмбаркадеро проделало огромадную работу, что бы к этому всему 'счастью' приспособиться. Имейте уважение.
-
> Дмитрий Белькевич (14.08.09 14:12) [12] так почему-же в Д2009 не работает сей код? Неверно определяется указатель на данные в VarBindList .
-
|