Форум: "Основная";
Текущий архив: 2005.10.16;
Скачать: [xml.tar.bz2];
ВнизНаследование и виртуальные функции Найти похожие ветки
← →
nastya (2005-09-22 15:15) [0]Привет! Киньте, пожалуйста, идею, где и как поискать ошибку. Я иссякла:(
Есть два класса TAnyDevice и его наследник TThisDevice. Общие функции TAnyDevice , конкретика у TThisDevice.
Есть две задачи прочитать и записать серийный номер. Чтение происходит нормально, а при записи Acsess Violation. На мой взгляд объявления и порядок выполнения для чтения и записи аналогичен. Но почему тогда ошибка только при записи??!! Вот объявления:
TAnyDevice
//запись данных в память
function WriteDataToEEprom(Addr:integer; Data:PByteArray;DataLen:word):boolean;
//чтение данных из памяти
function ReadDataFromEEprom(Addr:integer; var PData:PByteArray;DataLen:word):boolean;
//запись серийн. ном. в устройство открывая/закр. сеанс связи
function WriteSerialNumberOpenClose:boolean;virtual;
//чтение серийн. ном. из устройства открывая/закр. сеанс связи
function ReadSerialNumberOpenClose:boolean;virtual;
function WriteSerialNumber:boolean;virtual;
function ReadSerialNumber:boolean; virtual;
//чтение одного байта
function ReadByteFromEEprom(Addr:integer;var b:byte):boolean;virtual;abstract;
//запись одного байта
function WriteByteToEEprom(Addr:integer; b:byte):boolean;virtual;abstract;
TThisDevice
function ReadSerialNumber:boolean; override;
function WriteSerialNumber:boolean;override;
function ReadByteFromEEprom(Addr:integer;var b:byte):boolean;override;
function WriteByteToEEprom(Addr:integer; b:byte):boolean;override;
Порядок выолнения чтения
TAnyDevice .ReadSerialNumberOpenClose
TThisDevice.ReadSerialNumber
TAnyDevice .ReadDataFromEEprom
TThisDevice.ReadByteFromEEprom
Запись
TAnyDevice .WriteSerialNumberOpenClose
TThisDevice.WriteSerialNumber
TAnyDevice.WriteDataFromEEprom
TThisDevice.WriteByteFromEEprom<<--!!!! здесь баг
в теле TAnyDevice.WriteDataFromEEprom при попытке вызвать
WriteDataFromEEprom Access Violation.
← →
umbra © (2005-09-22 15:30) [1]Из хелпа про абстрактные методы:
You can call an abstract method only in a class or instance of a class in which the method has been overridden.
Т.е. их можно вызывать только в классе-наследнике,где они реализованы. В TAnyDevice WriteByteFromEEprom вызывать нельзя
← →
Digitman © (2005-09-22 15:30) [2]
> TAnyDevice.WriteDataFromEEprom
> TThisDevice.WriteByteFromEEprom<<--!!!! здесь баг
ЗАЧЕМ ДВАЖДЫ вызывать метод WriteByteFromEEprom() ОДНОГО И ТОГО ЖЕ объекта ?
ведь поскольку этот метод у класса-предка является виртуальным и он перекрыт в классе-потомке, то при первый же вызов - это вызов метода TThisDevice.WriteByteFromEEprom !
?
← →
Arm79 © (2005-09-22 15:30) [3]а все таки исходники то не мешало бы...
← →
nastya (2005-09-22 15:34) [4][2]
так я дважы и не вызызваю
в теле TAnyDevice.WriteDataToEEprom по количеству байт вызывается
WriteByteToEEprom перекрытый в классе TThisDevice
← →
nastya (2005-09-22 15:37) [5][1]
> Т.е. их можно вызывать только в классе-наследнике,где они
> реализованы. В TAnyDevice WriteByteFromEEprom вызывать нельзя
А как еще тогда?
Идеология записи мноджества байт общая -пишем их по одному в цикле. То есть это метод уровня TAnyDevice. А как конкретно этот байт закинуть знает только реальное устройство.
← →
Digitman © (2005-09-22 15:38) [6]
> так я дважы и не вызызваю
здрасть-приехали !
а ЭТО что ?
TAnyDevice.WriteDataFromEEprom
TThisDevice.WriteByteFromEEprom<<--!!!! здесь баг
используется один и тот же, судя по всему, объект..
← →
umbra © (2005-09-22 15:40) [7]
> в теле TAnyDevice.WriteDataToEEprom по количеству байт вызывается
> WriteByteToEEprom перекрытый в классе TThisDevice
Так вызывается ж в том классе, где он абстрактный! Его там как бы и нет вовсе, название одно! А можно его вызывать только там, где он перекрыт, т.е в TThisDevice, да и то это будет не TAnyDevice.WriteByteToEEprom, а TThisDevice.WriteByteToEEprom, о котором TAnyDevice ничего не знает.
← →
Digitman © (2005-09-22 15:41) [8]
> nastya
приводи уже РЕАЛЬНЫЙ код ... иначе - базар-вокзал ...
← →
nastya (2005-09-22 15:43) [9][6]
Торможу?? :)
function TAnyDevice.WriteDataToEEprom(Addr:integer; PData:PByteArray;DataLen:word):boolean;
var
i,a:integer;
b:word;
Begin
result:=true;
b:=0;
if DataLen<=0 then
exit;
repeat
a:=Addr+b;
result:=result and WriteByteToEEprom(a,PData[b]);
b:=b+1;
until (not result) or (b>DataLen-1);
End;
← →
Digitman © (2005-09-22 15:49) [10]э-э-э .. скорей я торможу) ...
тогда объясни мне, тундре, накой ляд ты сначала вызываешь Предок.WriteDataToEEprom, а следом Наследник.WriteByteToEEprom, если Предок при исполнении перекрытого в Наследнике WriteDataToEEprom и так уже вызывает тот самый WriteByteToEEprom ?
← →
nastya (2005-09-22 15:50) [11][7]
так реальный - то объект TThisDevice
← →
umbra © (2005-09-22 15:55) [12]А вы этот метод сделайте не абстрактным, а просто виртуальным, а в имплементации пусть он будет пустой или просто возвращает true
← →
nastya (2005-09-22 16:00) [13][10]
Еще раз. Сначала.
1)Device:=TThisDevice.Create
2)Device.WriteSerialNumberOpenClose (реально этот метод в TAnyDevice)
function TAnyMeter.WriteSerialNumberOpenClose:boolean;
Begin
result:=false;
if not HardOpenSession then exit;
result:=WriteSerialNumber; //Здесь переопределено в TThisDevice
CloseSession;
End;
function TThisDevice.WriteSerialNumber:boolean;
var
Dat:array[1..128] of byte;
Addr:word;
Len:byte;
Begin
result:=false;
здесь готовлю данные
if not WriteDataToEEprom(Addr,@Dat[1],Len) then //здесь реально TAnyDevice
begin
обработка ошибки
exit;
end;
result:=true;
End;
← →
nastya (2005-09-22 16:03) [14][13] попробую
просто на мой взгляд все должно работать нормально и так, то есть если я правильно понимаю, абстрактиные методы примерно для такого использования и преднозначены :)
← →
Digitman © (2005-09-22 16:13) [15]так...
базар по поводу виртуальности/абстрактности/наследования м.б. долгим и бесплодным - книга даст ВМСЕ ответы, ибо она - источник знаний.
поехали назад, к отправной точке сабжа, обладающей НЕОПОРОВЕРЖИМЫМИ конкретностями
цитирую :
> а при записи Acsess Violation
приведи дословно сообщение об исключении, конкретную строчку кода конкретного метода конкретного класса, при выполнении которой было возбуждено данное исключение
← →
nastya (2005-09-22 16:13) [16][13]
TAnyMeter=TAnyDevice -это я для простоты :)
← →
umbra © (2005-09-22 16:13) [17]
> umbra
> пусть он будет пустой
прошу прощения, не надо делать пустым. это ж функция
← →
nastya (2005-09-22 16:24) [18][15]
function TAnyDevice.WriteDataToEEprom(Addr:integer; PData:PByteArray;DataLen:word):boolean;
var
i,a:integer;
b:word;
Begin
result:=true;
b:=0;
if DataLen<=0 then
exit;
repeat
a:=Addr+b;
result:=result and WriteByteToEEprom(a,PData[b]);
b:=b+1;
until (not result) or (b>DataLen-1);
End;
Выдает:
Project.... raised exception EAccessViolation with message "Access violation at adress 00481F13 in module... Read of adress 0000001C".
Причем выдает при пошаговой отладке именно в этот момент -при попытке выполнить WriteByteToEEprom. Для отладки же пыталась строчкой раньше посмотреть self.ClassName - накрывается тогда здесь.
← →
nastya (2005-09-22 16:25) [19][17] ну это понятно
← →
nastya (2005-09-22 16:29) [20]Я даже не прошу, мне помогать реально найти ошибку, но КАК хотя-бы ее искать??
← →
Digitman © (2005-09-22 16:31) [21]
> nastya (22.09.05 16:29) [20]
> КАК хотя-бы ее искать?
именно ТАК и искать !
отправной точкой является локализованная тобой (в ходе пошаговой трассировки) трочка твоего кода, при выполнении которой возникает проблемная ситуация.
ты эту строчку локализовала ?
нет.
вот этим и займись !
← →
nastya (2005-09-22 16:34) [22][21]
Понятно, что проблема с памятью где-то не здесь. Здесь только результат. А как найти место реальной ошибки...
← →
umbra © (2005-09-22 16:37) [23]
> А как найти место реальной ошибки...
> function WriteByteToEEprom(Addr:integer; b:byte):boolean; virtual; abstract;
>
← →
Digitman © (2005-09-22 16:41) [24]
> как найти место реальной ошибки
трасс ируя пошагово код своей программы ... где F7 жмакнешь, а где F8 - по ситуации ... главное - ЛОКАЛИЗОВАТЬ "атомарный" вызов, т.е. тот вызов , происходящее в теле которого уже вне сферы твоей компетенции, например, вызов WinAPI-ф-ции
← →
nastya (2005-09-22 16:49) [25][24]
так в этом месте все и накрывается, я же писала[18]
result:=result and WriteByteToEEprom(a,PData[b]);
← →
Digitman © (2005-09-22 16:58) [26]
> nastya (22.09.05 16:49) [25]
ну а ПОШАГОВО-то пройти тело вызываемого при этом мсетода TThisDevice.WriteByteToEEprom в голову разве не пришло ?!
кто ж тебя заставляет на этой строчке жмакать именно F8 ?
жмакай F7 - и поехали !
шаг за шагом в теле того самого метода, который является перекрытием абстрактного метода TAnyDevice.WriteByteToEEprom ..
> Access violation at adress 00481F13 in module.
меню Search -> Find Error...
вводишь там 00481F13 - дебагер покажет тебе строчку в твоем проекте, где данная проблема имеет тебя)
← →
nastya (2005-09-22 17:02) [27][26]
Оно накрывается при ПОПЫТКЕ вызова WriteByteToEEprom ! Разумеется я бы просмотрела.
← →
Digitman © (2005-09-22 17:05) [28]кто "оно" ? конкретно ?
WriteByteToEEprom у тебя - НЕ атомарная ф-ция !
она имеет ТВОЮ СОБСТВЕННУЮ реализацию !
состоящую из собственноручно тобой написанных операторов !
так вот я и спрашиваю - на КАКОМ из операторов, находящихся в теле реализованного тобой метода TThisDevice.WriteByteToEEprom, происходит сабж ?!
← →
nastya (2005-09-22 17:07) [29][28]
result:=result and WriteByteToEEprom(a,PData[b]);
При нажатии F7 для выполнения ЭТОЙ строки выдается Access Violation.
Не успевает зайти ВНУТРЬ тела.
← →
Digitman © (2005-09-22 17:10) [30]тогда поехали разбираться с фактическими параметрами ... что, как, где объявлено, как инициализировано и т.д. и т.п. ..
← →
Digitman © (2005-09-22 17:12) [31]ПЕРВОЕ, что тебе д.было прийти в голову - это средствами Evaluate/Modify просмотреть, а что же все-таки ФАКТИЧЕСКИ ты пытаешься передать параметрами a и PData[b]
← →
nastya (2005-09-22 17:20) [32][31] Вот! Спасибо! Разумеется смотрела раньше, но сейчас со злости глянула внимательнее. И нашла :))
← →
Digitman © (2005-09-22 17:24) [33]
> nastya (22.09.05 17:20) [32]
> со злости глянула
вот видишь !)
иной раз злость (на самою себя или на свою недогадливость) - весьма полезное состояние души !
)
← →
nastya (2005-09-22 17:26) [34]Не, злость была на Вас, что типа я такая недогадливая и элементарных вещей не сделала :)))
← →
Digitman © (2005-09-22 17:29) [35]понимаю)
но они действительно элементарные !
и мной изначально таки подразумевалось, что уж здесь-то дилетантского прокола с Вашей стороны как бы и не подразумевается)
← →
nastya (2005-09-22 17:32) [36]Так я все и сделала .... вроде бы
Ладно, в следующий раз буду внимательнее. Спасибо
← →
Digitman © (2005-09-22 17:32) [37]
> nastya (22.09.05 17:26) [34]
согласиь, все же встр.отладчик - могучая штука ?
и СВОБОДНОЕ ПРАКТИЧЕСКОЕ владение им (и многими основными его фичами) намного ускоряет ход отладки ?)
← →
nastya (2005-09-22 17:35) [38]Только он иногда глючит. Реально с этим сталкивалась. Поэтому, вместо того, чтобы еще раз просмтотреть, начинаю копать глубже.
← →
Digitman © (2005-09-22 17:47) [39]
> nastya (22.09.05 17:35) [38]
> он иногда гл
врешь ведь)
НЕпонимание тобой работы дебагера в конкретных ситуациях НЕ означает его "глючность" в принципе.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.10.16;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.043 c