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

Вниз

Наследование и виртуальные функции   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.158 c
2-1126619915
SMATMP
2005-09-13 17:58
2005.10.16
Bitmap color attributes


2-1125550789
Diller
2005-09-01 08:59
2005.10.16
Копирование файлов


14-1127583183
lookin
2005-09-24 21:33
2005.10.16
3D-графики с возможностью сохранения в pdf


9-1117733503
Валера
2005-06-02 21:31
2005.10.16
Взрыв на OpenGL


6-1119475580
pool
2005-06-23 01:26
2005.10.16
WebServer