Форум: "Основная";
Текущий архив: 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.032 c