Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.015 c
8-1115220389
Gear
2005-05-04 19:26
2005.09.11
Как осуществить запись звука с микрофона средствами DirectSound?


14-1124274282
Дмитрий_Б
2005-08-17 14:24
2005.09.11
Навеяно недавней веткой


6-1116867813
noname:))
2005-05-23 21:03
2005.09.11
Как вытянуть имя из ответа на пинг?


1-1124462191
murz
2005-08-19 18:36
2005.09.11
Сжатие приложений


1-1124657325
maximmsm
2005-08-22 00:48
2005.09.11
форма поверх основной формы





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский