Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.11.28;
Скачать: [xml.tar.bz2];

Вниз

Access violation at adress ...   Найти похожие ветки 

 
novice_man ©   (2004-11-11 20:07) [0]

Уважаемые мастера, возникла одна проблемма.
Вылетает одна и таже ошибка "Access violation at address 00000000 Read of address 00000000." Вылетает если в программе были выполнены определенные действия в момент завершения программы . При пошаговом выполнении ошибка не вылетает. Вернее эту ошибку дельфи не перехватывает, ошибка возникает но в дельфи остается [Running]. Пытался отловить через MemProof, но он тоже не видит этой ошибки. ПОМОГИТЕ!!!!! Неделя прошла зря! Ненавижу эти нули.


 
Alx2 ©   (2004-11-11 20:10) [1]

Скорее всего идет обращение к кому-то давно мертвому.
Ну и нужен код.


 
novice_man ©   (2004-11-11 20:13) [2]

<Alx2>
При пошаговом завершении нет ошибки!
Код больно уж громоздкий.


 
Alx2 ©   (2004-11-11 20:18) [3]

>novice_man ©   (11.11.04 20:13) [2]
А "определенные действия" - это какие?
Возможно, в процессе завершения работы приложения уничтожаются объекты, связанные с пользовательским интерфейсом, до того, как необходимость в них отпала.

>Код больно уж громоздкий.

Тогда на кофейной гуще гадать остается.


 
novice_man ©   (2004-11-11 20:45) [4]

Попробую уточнить насколько это возможно.

Программа - архивация (пока без упаковки) некоторых файлов.
Две библиотеки: 1- для сбора и обработки файлов в указанном  
                  каталоге и ниже.
               2- архивация.

библиотеки подлючаются динамически.

загрузка библиотеки №1 выполняется при старте программы для получения списка файлов, список передается в виде результата функции TList содержащий тип pMyRecord.

загрузка библиотеки №2 выполняется при старте программы для
получения списка архивированных файлов, список передается в виде результата функции TList содержащий тип pMyRecord.

Динамическая загрузка применена для того что бы иметь возможность в процессе выполнения программы изменить источник данных (для разных типов файлов разные библиотеки)

Действия приводящие к ошибке:

Выполняю архивацию, после завершения архивации выполняется повторный опрос архива, если после этого сменить библиотеку-архиватор (произойдет выгрузка и подключение dll`ки) то при завершении - ошибка.

Если исключить архивацию, все работает нормально.
А сейчас куски кода по загрузке-выгрузке библиотек:

type
  pDevice = ^tDevice;
  tDevice = record
                handle: Cardinal;
                user_name_device: string;
                system_name_device: string;
                type_device: byte;
                device_dll: string;
                hint: string;
                hint_tmp: string;
                error_byte: byte;
                error_msg: string;
                end;

var
device_get, device_arh: tDevice;

подключени библиотек

procedure GetDevice(var device: tDevice);
var
fgettypelib: function: byte;
begin  
try
 device.error_byte := 0;
 device.handle := LoadLibrary(pChar(device_folder + "\" + device.device_dll));
 if device.handle <> 0 then begin
    @fgettypelib := nil;
    @fgettypelib := GetProcAddress(device.handle, "gettypelib");
    if @fgettypelib <> nil then begin
       if fgettypelib <> device.type_device then device.error_byte := 3;
       end else device.error_byte := 2;
    end else device.error_byte := 1;
except device.error_byte := 5 end;
if device.error_byte > 1 then FreeLibrary(device.handle);
case device.error_byte of
     1: device.error_msg := "Ошибка: "" + device.device_dll + """;
     2: device.error_msg := "Ошибка!";
     3: device.error_msg := "Ошибка!";
     5: device.error_msg := "Ошибка: "" + device.device_dll + """;
     end;
end;

получение списка фалов

function GetList: boolean;
var
fGetData: function(Folder_Device: string): TList;
ListFile: TList;
fPosRead: integer;
fItem: pItem;
fItem_device: pFile_device;
begin
ListFile := TList.Create;
try
if device_get.handle > 32 then begin
   @fGetData := nil;
   @fGetData := GetProcAddress(device_get.handle, "GetData");
   if @fGetData <> nil then ListFile.Assign(fGetFlightData(device_folder), laCopy)
      else MessageBox(hwnd_mainwindow, "?? ??????? ????? ???????????? ??????????.", "?????? ????????? ?????? ???????.", 16);
   end else MessageBox(hwnd_mainwindow, "?? ???????? ????? ?????????? ????????? ??????????.", "?????? ????????? ?????? ???????.", 16);
except MessageBox(hwnd_mainwindow, "??????????? ??????!", "?????? ????????? ?????? ???????.", 16); end;
CountFlight := ListFile.Count;
result := ListFile.Count > 0;
ListFiles := TList.Create;
if result then
   for fPosRead := 0 to ListFile.Count - 1 do begin
       fItem_device := ListFile.Items[fPosRead];
       New(fItem);
       fItem^._id := fItem_device^;
       fItem^._id. file_id.name_device_source := device_get.system_name_device;
       fItem^.archive_p := false;
       fItem^.base_p := true;
       fItem^.select := 0;
       ListFiles.Add(fItem);
       end;
ListFile.Destroy;
end;

получени списка файлов из архива

function GetListArchFiles: boolean;
    function CheckFlights(FirstItem: pItemFile; SecondfItem: pFlightFile_device): boolean;
    begin
     Result := (FirstItem^.file_id = SecondfItem^.file_id);

    end;

var
fGetListArchFiles: function(Folder_Device: string): TList;
ListFile: TList;
fPosRead_1, fPosRead_2, fCountFile: integer;
fItem: pItem;
fItem_device: pFile_device;
fDoneMatch: boolean;
begin
ListFile := TList.Create;
try
if device_arh.handle > 32 then begin
   @fGetListArchFiles := nil;
   @fGetListArchFiles := GetProcAddress(device_arh.handle, "GetListArchFiles");
   if @fGetListArchFiles <> nil then ListFile.Assign(fGetListArchFiles(device_folder), laCopy) // пробовал ListFile := fGetListArchFiles(device_folder)
      else MessageBox(hwnd_mainwindow, "?? ??????? ????? ???????????? ??????????.", "?????? ????????? ?????? ???????.", 16);
   end else MessageBox(hwnd_mainwindow, "?? ???????? ????? ?????????? ????????? ??????????.", "?????? ????????? ?????? ???????.", 16);
except MessageBox(hwnd_mainwindow, "??????????? ??????!", "?????? ????????? ?????? ???????.", 16); end;
CountArch := ListFile.Count;
result := ListFile.Count > 0;
if result then begin
   fCountFile := ListFlight.Count;
   for fPosRead_1 := 0 to ListFile.Count - 1 do begin
       fItem_device := ListFile.Items[fPosRead_1];
       fDoneMatch := false;
       for fPosRead_2 := 0 to fCountFile - 1 do begin
           fItem := ListFiles.Items[fPosRead_2];
           if CheckFlights(fItem, fItem_device) then begin
              fItem^.archive_p := true;
              Inc(fItem.select, 2);
              fDoneMatch := true;
              end;
           end;
       if not fDoneMatch then begin
          New(fItem);
          fItem^._id := fItem_device^;
          fItem^.archive_p := true;
          fItem^.base_p := false;
          fItem^.select := 4;
          ListFlight.Add(fItem);
          end;
       end;
   end;
ListFile.Destroy;
end;

выгрузка библиотек

procedure FreeDevice(var device: tDevice);
begin
if device.handle > 32 then begin
   FreeLibrary(device.handle);
   device.handle := 0; ????????? это уже добавленно от бессилия
   end;
end;

при завершении сначала освобождаются все списка TList, а потом выгружаю библиотеки, хотя разници не заметил.


 
begin...end ©   (2004-11-11 20:55) [5]

novice_man ©   (11.11.04 20:45) [4]

Я бы в первую очередь заключил использование TList в try/finally. И использовал бы Free вместо Destroy.

Т.е.:

with TList.Create do
 try
   ...
 finally
   Free
 end.


 
GuAV ©   (2004-11-11 20:59) [6]

novice_man ©   (11.11.04 20:07)
Access violation at address 00000000 Read of address 00000000."


IMHO, вызов процедуры (или метода), которая равна nil.


 
novice_man ©   (2004-11-11 21:00) [7]

begin...end ©  (11.11.04 20:55) [5]


with TList.Create do
try
 ...
finally
 Free
end.

Принято. Но это "не спасет отца русской демократии" :-(.


 
novice_man ©   (2004-11-11 21:02) [8]

GuAV ©  (11.11.04 20:59) [6]

Если бы вы смогли подсказать как найти эту процедуру или метод.


 
Alx2 ©   (2004-11-11 21:09) [9]

>novice_man ©   (11.11.04 20:45) [4]

function GetList: boolean;
var
 fGetData: function(Folder_Device: string): TList;
 ListFile: TList;
 fPosRead: integer;
 fItem: pItem;
 fItem_device: pFile_device;
begin
 ListFile := TList.Create;
 try
   if device_get.handle > 32 then begin
     @fGetData := nil;
     @fGetData := GetProcAddress(device_get.handle, "GetData");
     if @fGetData <> nil then ListFile.Assign(fGetFlightData(device_folder), laCopy)


Пока не особо въехал. Но вопрос возник.
Выделенное место - так и задумывалось, а не fGetData?


 
novice_man ©   (2004-11-11 21:11) [10]

Alx2 ©  (11.11.04 21:09) [9]

Конечно правильно fGetData, извините.


 
begin...end ©   (2004-11-11 21:20) [11]

novice_man ©   (11.11.04 20:45) [4]

А кто такой ListFlight? И действительно ли ListFlight.Count = ListFiles.Count ?


 
Alx2 ©   (2004-11-11 21:22) [12]

>novice_man ©
Ничего пока не нашел. Наверное, где-то еще портится.

На всякий случай: в DLL и в основном проекте (dpr) используется ShareMem?


 
novice_man ©   (2004-11-11 21:26) [13]

Alx2 ©  (11.11.04 21:22) [12]
Нет не испоьзуется ShareMem.


 
Alx2 ©   (2004-11-11 21:29) [14]

> novice_man ©   (11.11.04 21:26) [13]
Вот и разобрались :)

Мастер DLL (от Delphi) вот что пишет при создании новой DLL:

library Project1;

{ Important note about DLL memory management: ShareMem must be the
 first unit in your library"s USES clause AND your project"s (select
 Project-View Source) USES clause if your DLL exports any procedures or
 functions that pass strings as parameters or function results. This
 applies to all strings passed to and from your DLL--even those that
 are nested in records and classes. ShareMem is the interface unit to
 the BORLNDMM.DLL shared memory manager, which must be deployed along
 with your DLL. To avoid using BORLNDMM.DLL, pass string information
 using PChar or ShortString parameters.
}

uses
 SysUtils,
 Classes;

{$R *.res}

begin
end.


 
Alx2 ©   (2004-11-11 21:31) [15]

То есть. В dll в секции uses первым в списке обязан идти модуль ShareMem.
В файле проекта-хоста (dpr)  - то же самое.


 
novice_man ©   (2004-11-11 21:33) [16]

Alx2 ©  (11.11.04 21:29) [14]

STRING????????????????


 
Alx2 ©   (2004-11-11 21:34) [17]

>novice_man ©   (11.11.04 21:33) [16]
Крик души не понял :)


 
novice_man ©   (2004-11-11 21:37) [18]

Где то встречал что в DLL надо использовать ShortString вместо  String.


 
Alx2 ©   (2004-11-11 21:40) [19]

>novice_man ©   (11.11.04 21:37) [18]
Поставь на первое место в uses ShareMem. И в голове DLL, и в голове хоста. Этого для  использования string достаточно.


 
novice_man ©   (2004-11-11 21:43) [20]

Alx2 ©  (11.11.04 21:31) [15]
Добавил. Теперь дельфи выловил ошибку, но в окне CPU нули и теперь ошибка вылетает после запуска и останова программы.


 
Alx2 ©   (2004-11-11 21:44) [21]

Стэк вызовов видно?


 
novice_man ©   (2004-11-11 21:48) [22]

Перекомпилировал весь проект, ошибка исчезла. Пока не смог повторить ошибку. Спасибо Axl2.


 
Alx2 ©   (2004-11-11 21:48) [23]

Удачи! :)



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

Форум: "Основная";
Текущий архив: 2004.11.28;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.037 c
3-1098802934
Elast
2004-10-26 19:02
2004.11.28
Массивы в ХП


1-1100334175
AlexBragutsa
2004-11-13 11:22
2004.11.28
Для начинающего Делфиста


11-1083335243
RTWolf
2004-04-30 18:27
2004.11.28
Как проверить создан ли объект (например форма)?


14-1100110705
Sun bittern
2004-11-10 21:18
2004.11.28
Крохоборка ХР


14-1100168494
iis_work
2004-11-11 13:21
2004.11.28
Нужны исходники





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский