Форум: "Основная";
Текущий архив: 2005.09.11;
Скачать: [xml.tar.bz2];
ВнизАкцес виолейшен в длл Найти похожие ветки
← →
Deep © (2005-08-16 17:53) [0]в длл, ни с того ни с сего начала возникать ошибка на этой строчке
library mlib;
uses
ShareMem,
SysUtils,
Classes,
Controls,
Forms,
IniFiles,
......
var
IniFileName: string;
......
//вот здесь
IniFileName := ChangeFileExt(Application.ExeName, ".ini");
раньше работало нормально, а сейчас ошибка
в отладчике ExeName показывает имя именно приложения, а не длл, если написать
IniFileName := Application.ExeName + ".ini";
то ошибка(акцес виолейшен) пропадает.
Но тогда возникает ошибка в следующей(столь же банальной строке) строке
IniFile := TIniFile.Create(IniFileName);
это опять какая-то фигня с менеджерами памяти, хотя и в длл и в приложении я уже подключил ShareMem первым в списке.
Причем ситация все больше становится туманной ввиду того, что эта длл уже нормально работала. А перестала работать после того как я внес довольно таки много изменений в код приложения, правда этот измененный код ни коим образом не касается этой длл.
Возможно нужно еще включить какие-то дерективы?
Или увеличить стек?
ShareMem включен первым модулем в оба дпр-а(и приложение, и длл).
← →
Eraser © (2005-08-16 18:00) [1]Deep © (16.08.05 17:53)
Возможно объект Application для ДЛЛ не проинициализирован. Возникает ли ошибка если обратиться к другим полям Application?
← →
deep © (2005-08-16 18:08) [2]
> в отладчике ExeName показывает имя именно приложения, а
> не длл, если написать
> IniFileName := Application.ExeName + ".ini";
> то ошибка(акцес виолейшен) пропадает.
> Но тогда возникает ошибка в следующей(столь же банальной
> строке) строке
>
> IniFile := TIniFile.Create(IniFileName);
← →
deep © (2005-08-16 18:16) [3]в длл используются модули
uses
ShareMem,
SysUtils,
Classes,
Controls,
Forms,
IniFiles,
DB, DBTables, BDE;
а также используются глобальные переменные
var Database: TDatabase;
Query: TQuery;
QueryArray: array of TQuery;
указатели на TQuery используются в главной програме посредством экспортируемых функций типа:
function QueryOpen(s: PChar): TDataset;
адреса на которые приложение получает при загрузке длл.
Насколько я понял, при выполнении "слетает" стек(регистр esp) из-за непонятных проблем с управлением памятью. Но в чем же проблема конкретно - непонятно.
← →
TUser © (2005-08-16 18:19) [4]Когда ошибки возникают на совершенно "чистых" строках - типичный пример того, что ошибка в другом месте. Вспоминай, - после какого изменения программы появился баг.
← →
deep © (2005-08-16 18:38) [5]
> TUser ©
не первый год замужем. :))
Суть такова: из приложения нужно было вынести в длл работу с БДЕ(TDatabase, TQuery) и оставить только работу с результирующими наборами(TDataset). Что собственно я и сделал. В результате избавился в приложении от модуля dbtables и испульзую только db.
В длл используется и тот и другой. Пробовал однако добавть модуль dbtables в приложение -- проблемы не решает.
И еще в главном приложении часть констант оформил в секцию resorcestring. Возможно это тоже могло как то косвенно повлиять?
Все.
← →
isasa © (2005-08-16 18:49) [6]А не проще передавать параметром имя ini файла в процедуру(функцию) библиотеки, и не искать где чей Application.
Что, кстати логичней.
← →
deep © (2005-08-16 18:54) [7]
> isasa ©
если бы дело было именно в Application, я бы так и сделал. Но проблема более масштабная. Я могу закоментировать этот код вообще, ошибка лезет через пару строчек ниже.
← →
Alexander Panov © (2005-08-16 18:59) [8]deep © (16.08.05 18:54) [7]
Все же приведи побольше кода.
А еще подумай, может быть Application вовсе не создан объект в DLL?
Если надо получить имя пути, где находится DLL, используй такой метод:
function CPath: String;
var
p: array[0..1024] of Char; // или [0..MAX_PATH+1]
n: Integer;
begin
n := GetModuleFileName(HINSTANCE,@p[0],1024);
Result := "";
if n>0 then
begin
SetLength(Result,n);
Move(p[0],Result[1],n);
end;
end;
...
CGIPath := ExtractFilePath(CPath);
← →
isasa © (2005-08-16 19:12) [9]Выдержка из Delphi help-а
Global variables in a library
Global variables declared in a shared library cannot be imported by a Delphi application.
A library can be used by several applications at once,
but each application has a copy of the library in its own process space with its own set of global variables.
For multiple libraries--or multiple instances of a library--to share memory, they must use memory-mapped files.
Refer to the your system documentation for further information.
ИМХО. Убирать глобальные переменные
var Database: TDatabase;
Query: TQuery;
QueryArray: array of TQuery;
← →
Юрий Зотов © (2005-08-16 19:12) [10]> Deep
Попробуйте проинициалировать в DLL еще и глобальную переменную Session (значением из EXE).
Либо наооборот (если сессия открывается в DLL). В общем, Session при работе с BDE должен быть везде один и тот же (подобно Application и Screen).
← →
Eraser © (2005-08-16 19:12) [11]deep ©
Надо просматривать весь код, начиная с момента, который "инициирует" действия в [0].
Т.е. например инициатором может быть нажатие какой-то кнопки или реакция на какое-то событие, вам виднее.
← →
deep © (2005-08-16 19:28) [12]
> isasa ©
в даном случае мне НЕ нужно чтоб это были действительно "глобальные переменные". Мне нужны именно копии этих переменных. Но суть не в этом, потому как длл будет юзать только одно приложение и доступ к этим переменным из других приложений(или копий этого приложения) впринципе не планируется.
> Юрий Зотов ©
> Попробуйте проинициалировать в DLL еще и глобальную переменную
> Session
весь фокус в том, что до работы с БДЕ в даном случае даже не доходит ход. Вначале в длл я считываю настройки из ини-файла(название базы данных, путь к файлам и т.п.)... вот тут то и подкашивает. Причем не на реальной ошибке, а из-за проблем с управлением памятью....
> Eraser © (16.08.05 19:12) [11]
ага, под отладчиком смотрел где вылетает... То что, на нормально написаной строке вылетает - это уже понятно. Смотрел регистры поцессора: видно как при каком-то из "call -$00006463" регистр ESP(стек) уходит за допустимые пределы. Вот почему?
← →
deep © (2005-08-16 19:39) [13]
library paradox;
uses
ShareMem,
SysUtils,
Classes,
Controls,
Forms,
IniFiles,
DB, DBTables, BDE,
//ReestrUpd in "ReestrUpd.pas" {fmReestrUpd},
PlugConfig in "PlugConfig.pas" {fmPluginConfig};
{$R *.res}
var Database: TDatabase;
Query: TQuery;
QueryArray: array of TQuery;
IniFileName: shortstring;
Initialized: boolean;
optDatabase, optUsername, optPassword: string;
procedure PluginInit;
var IniFile: TIniFile;
const
BdeError = "Не удается проинициализировать Borland Database Engine (BDE)!";
begin
//проверим на работоспособность BDE
if dbiInit(nil) <> DBIERR_NONE then
Application.MessageBox(BdeError, "Ошибка");
{
//если нужно, проапдейтим реестр(БДЕ)
if not CheckUpdatedFlag then begin
fmReestrUpd:= TfmReestrUpd.Create(Application);
try
fmReestrUpd.ShowModal;
finally
fmReestrUpd.Free;
end;
end;
}
//инициализация плугина
Database := TDatabase.Create(Application); //Application
Database.Name := "Database";
Database.DatabaseName := "dbDeepOWN";
Database.LoginPrompt := false;
Database.DriverName := "STANDARD";
Database.Params.Values["DEFAULT DRIVER"] := "PARADOX";
Database.Params.Values["ENABLE BCD"] := "FALSE";
// >>>>>>>>>>>>>>>> вылет идет вот здесь >>>>>>>>>>>>>>>>
IniFileName := ChangeFileExt(Application.ExeName, ".ini");
IniFile := TIniFile.Create(IniFileName);
with Database do begin
//читаем из ини-файла и присваиваем значения глобальным переменным
optDatabase := IniFile.ReadString(PluginName, "Database", "");
//формируем строку соединения
Database.Params.Values["PATH"] := optDatabase;
Open;
end;
Query := TQuery.Create(Application);
Query.DatabaseName := Database.DatabaseName;
Initialized := true;
end;
.....
← →
Eraser © (2005-08-16 19:42) [14]deep © (16.08.05 19:39) [13]
// >>>>>>>>>>>>>>>> вылет идет вот здесь >>>>>>>>>>>>>>>>
Дык ошибка тогда тутDatabase.Params.Values["ENABLE BCD"] := "FALSE";
← →
isasa © (2005-08-16 20:50) [15]Зачем,
Database := TDatabase.Create(Application);
ведь можно
Database := TDatabase.Create(nil);
ведь совершенно очевидно, что освобождать придется ручками
Database.Close;
Database.Free;
Ведь совершенно очевидно, что Application содержит "левую" ссылку(не nil). Соглашусь на обратное, если кто-то укажет место, где она инициализируется правильным значением.
← →
Slym © (2005-08-17 04:31) [16]используются старые dcu- удали
← →
deep © (2005-08-17 10:02) [17]
> Eraser © (16.08.05 19:42) [14]
Нет, и еще раз нет :))
> isasa ©
> Database := TDatabase.Create(Application);
> ведь можно
> Database := TDatabase.Create(nil);
согласен, поменял
теперь ошибка стала вываливыаться еще раньше,
на столь же безобидной функции
function PluginInfo: PChar;
begin
PluginInfo := "Обеспечивает возможность работы клиента с таблицами базы Paradox (с использованием BDE).";
end;
> Slym ©
удалил, не помогает
← →
Digitman © (2005-08-17 13:04) [18]
> ошибка стала вываливыаться
какая ошибка-то ?
гадать будем ?
уж 17 постов в дискуссии, а ТОЧНОЙ инф-ции об ошибке как не было так и нет ...
← →
deep © (2005-08-17 14:35) [19]
> Акцес виолейшен в длл [D7, WinXP]
а ошибка в сабже описана
← →
Digitman © (2005-08-17 15:25) [20]
> ошибка в сабже описана
где ?
> возникает ошибка
> акцес виолейшен
ЭТО ты называешь "описанием ошибки" ?
← →
deep © (2005-08-17 18:34) [21]access violation at 0x0040c3d5: write of address 0x00030f4c
после поледних изменений в коде вываливается на повторном вызове экспортируемой функцииfunction PluginInfo: PChar;
begin
PluginInfo := "Обеспечивает возможность работы клиента с таблицами базы Paradox (с использованием BDE).";
end;
← →
deep © (2005-08-17 19:34) [22]если скомпилировать(и приложени, и длл) с runtime-пакетами, то ошибка немного модифицируется
access violation at adress xxxxxxxx in module dcc70.dll
Read of adress xxxxxxxx
← →
Digitman © (2005-08-18 08:11) [23]
> access violation at 0x0040c3d5
собираешь exe-проект со всеми опциями встр.отладки, запускаешь из-под IDE, тут же вызываешь меню Search -> Find Error .., вводишь 0040c3d5 - и дебагер показывает тебе строчку твоего кода, при выполнении которой произошло исключение
← →
sniknik © (2005-08-18 08:55) [24]Digitman © (18.08.05 08:11) [23]
и это не поможет... ;)
у меня почемуто такое впечатление, что он какимито действиями портит код, к примеру пишет данные по "сбитому" указателю, тогда команда на которой возникает исключение это будет фактически то место куда писались данные в код, а ошибка по которой это произошло совершенно в другом месте - где это пишется.
(попытка обьяснить "плавающее" место глюка)
deep
проверь места где работаеш с динамическими переменными массивами, выделение памяти, "ранже чек еррор" проверку включи если выключал, и т.к. это dll то модели вызова процедур сравни в dll и exe.
вот к примеру, работа с памятью
function PluginInfo: PChar;
begin
PluginInfo := "Обеспечивает возможность работы клиента с таблицами базы Paradox (с использованием BDE).";
end;
тип PChar, а где под него выделение памяти? куда запишется строка? проверь, замени все PChar на string, ShareMem ты все одно используеш. чего тогда "напрягаться" следить за PChar-ми.
← →
evvcom © (2005-08-18 08:58) [25]И еще. Автор, используя передачу объектов между exe и dll без компиляции с runtime packages, рискует нарваться на другие "абсолютно непонятные" ошибки. Имея две (или более :) )реализации классов, создавая объект одного класса, а обрабатывая его методами другого, где-нибудь в недрах vcl может встретить конструкцию вида
if AnyObject is TAnyObject then
и получить соответственно различные результаты при использовании и не использовании runtime packages. Почему-то на это никто не обращает внимания.
← →
Digitman © (2005-08-18 09:07) [26]
> sniknik © (18.08.05 08:55) [24]
> тип PChar, а где под него выделение памяти?
она уже выделена - в секции инициализированных данных длл-модуля
← →
--=ХР=-- (2005-08-18 10:50) [27]function QueryOpen(s: PChar): TDataset;
Отстрел башки... Переписать все заново. И забыть о передаче объектов между разными исполняемыми модулями. Только простые типы данных. Или интерфейсы.
← →
Slym © (2005-08-19 05:11) [28]С рантаймами не пользуй шаремем.
И на кой тебе при шаремем и рантаймами PChar?
Открой окно CPU (Alt+Ctrl+C) и трасируй там, если в PluginInfo вызывается LStrClr - то все ясно
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.09.11;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.013 c