C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Непонятный Access violation при закрытии формы
** pasha
Отправлено: 30.06.2004, 11:34


Не зарегистрирован







Непонятная ситуация.
Есть программа exe, во время работы она может
динамически подгружать dll (до конца работы программы)

Работает все нормально.

Если dll так и не вызывалась — завершение программы проходит
без ошибок.

Если dll вызывалась — зависит от Build:

1. Если Build -> Linker -> стоит галочка в Use Dynamic RTL — программа
завершается без ошибок.

2. Если галочку снять — при завершении программы (закрытии главной
формы по нажатию на [х]), выскакивает непонятный
AccessViolation.
Обработчик (OnClose) отсутствует.

Может у кого-нибудь такое было, что-то посоветуете ?
Asher
Отправлено: 30.06.2004, 12:25


Мастер участка

Группа: Модератор
Сообщений: 550



Скорей всего при выходе не удаляешь объект, созданный в dll
Или удаляешь, но в основной программе.
Воспользуйся CodeGuard'ом
** pasha
Отправлено: 30.06.2004, 12:48


Не зарегистрирован







А как его включить и где ?
В exe или в каждой из подгружаемых dll тоже ?
Asher
Отправлено: 30.06.2004, 13:10


Мастер участка

Группа: Модератор
Сообщений: 550



QUOTE
А как его включить и где ?

Project->Options...->CodeGuard->CodeGuard Validation
QUOTE
В exe или в каждой из подгружаемых dll тоже ?

Для начала можно только в ехе wink.gif
** pasha
Отправлено: 30.06.2004, 13:14


Не зарегистрирован







QUOTE

Error 00047. 0x310000 (Thread 0x0590):
Bad parameter: A bad memory block (0x141E888) has been passed to the
function.
Error 00052. 0x310000 ® (Thread 0x0590):
Bad parameter: A bad memory block (0x31DA650) has been passed to the
function.


Включил.
Во время работы программы ничего не изменилось,
никаких сообщений не появлялось, при закрытии — опять
выскочила та-же ошибка.

Если я правильно понял, то он создал вот такой .cgl файл
Это все, или он может что-то еще мне сказать,
и что делать дальше с этими 2 ошибками ?
Asher
Отправлено: 30.06.2004, 13:28


Мастер участка

Группа: Модератор
Сообщений: 550



Добавте еще
Project->Options...->Linker->Use Debug Librares

И откройте окно
View->Debug Windows->Code Guard Log
** pasha
Отправлено: 30.06.2004, 14:06


Не зарегистрирован







К сожалению, в этом окошке ничего не появляется,
ошибка вылетает только после закрытия главного
окна программы.

В .cgl файле вижу только вот это:

QUOTE

Error 00045. 0x310000 (Thread 0x0454):
Bad parameter: A bad memory block (0x144E960) has been passed to the
function.


Asher
Отправлено: 30.06.2004, 14:22


Мастер участка

Группа: Модератор
Сообщений: 550



Не густо. Надо подумать.
Кстати где вы делаете FreeLibrary ?
** pasha
Отправлено: 30.06.2004, 14:41


Не зарегистрирован







В exe. При закрытии формы (завершении программы)
(см на 3 темы ниже тему "Выгрузка dll" )

Но это ни на что не влияет, делаю я эту выгрузку
или нет, даже если и не делаю,
ошибка вылетает все равно.

И что непонятно, ведь если оставить галочку
Linker -> Use Dynamic Library, никакой ошибки не вылетает.

Пробовал на другом компе (отладочном), без установленного
С++Builder 6 — все то-же самое:

Скопировал программу, она затребовала еще естественно
borlndmm.dll и сс3260mt.dll (c галочкой в Use Dynamic Library)
скопировал их в папку с программой — все работает без ошибок,
теперь
убил эти 2 dll, скопировал и запустил программу (без галочки в Use Dynamic Library), то есть по идее всё включилось в это exe — работает
с той-же самой ошибкой.


Что подозреваю — в своих динамически загружаемых dll
создаю формы:

CODE

#include "UFDLL.h"
extern "C" void __declspec(dllexport) myFunc(char* sTbl);

void myFunc(char* sTbl)
{
 char tmp[100];
 for(int i=0; i<100; i++) tmp[i] = '\0';

 TFDLL* myForm = new TFDLL(Application);
 strcpy(tmp, sTbl);
 myForm->sTbl = AnsiString(tmp);
 myForm->ShowModal();
}


Эту форма при закрытии должна удаляться:
CODE

void __fastcall TFDll::FormClose(TObject *Sender,
     TCloseAction &Action)
{
    Action = caFree;
}


Может тут что не так ?
(Пробовал и без Action = caFree, то есть
в myFunc делал: delete myForm;
да и просто не удалял — не помогает.)


Asher
Отправлено: 30.06.2004, 14:53


Мастер участка

Группа: Модератор
Сообщений: 550



Когда стоит Linker -> Use Dynamic Library они работают в одном адресном пространстве. Поэтому ошибки и нет.
Посмотри темы по форуму BorlandXportal:
Как корректно вызвать форму из DLL?
и
Использование DLL с VCL-формами
** pasha
Отправлено: 30.06.2004, 17:01


Не зарегистрирован







Почитал, попробовал.
и Application->Handle присваивал
и сам Application — увы, не помогло.

Без галочки в Use Dynamic Library все работает,
с галочкой в в Use Dynamic Library — при завершении — ошибка.

Но это надо таскать эти 2 библиотеки, да возможно
что где-то это и по-другому сглючит. sad.gif
** pasha
Отправлено: 30.06.2004, 17:04


Не зарегистрирован







То есть наоборот,
Без галочки в Use Dynamic Library — при завершении — ошибка,
с галочкой в в Use Dynamic Library — все работает,
AVC
Отправлено: 01.07.2004, 08:36


Ветеран

Группа: Модератор
Сообщений: 1583



Если вы в dll сбрасываете Borland'овские формы или функции, то могу поделиться опытом использования. Схема отработана давным давно и ни разу не заглючила независимо от галочек.

1. Части собораются в Borland'овские пакеты bpl (ни чем не отличаются от dll за исключением именования глобальных символов).
2. Пакеты подключаются либо статически (в менеджере проекта) либо динамически (LoadPackage)
3. Глобальные переменные и функции описываются
CODE

// для использования
extern PACKAGE void __fastcall sShow_Okno (const int pPersonalAccountID);
extern PACKAGE AnsiString Computer_Name;

// в пакете
AnsiString Computer_Name;

PACKAGE void __fastcall sShow_Okno (const int pPersonalAccountID)
{
TF_HACalk *frm = new TF_HACalk(Application);
try {
frm->Visible = false;
if (frm->Prepare(pPersonalAccountID,NULL)) frm->ShowModal();
} // try

catch (Exception &xcp) { OEMessage_Show(xcp.Message); }

delete frm;
}


4. Работа с пакетом
5. Выгрузка пакета (варианты см. тему ...dll) (UnloadPackage)
MDM
Отправлено: 01.07.2004, 10:47


Ученик-кочегар

Группа: Участник
Сообщений: 23



QUOTE (** pasha @ 30/06/2004, 12:36)
зависит от Build:

2. Если галочку снять — при завершении программы (закрытии главной
формы по нажатию на [х]), выскакивает непонятный
AccessViolation.
Обработчик (OnClose) отсутствует.

Может у кого-нибудь такое было, что-то посоветуете ?

Может виноват Application?
При статической линковке Application берется от приложения (Я так думаю...???) и тогда:
Выгружается dll — форма удаляется, далее Application находит у себя ссылку на форму (отсюда -> new TForm(Application)) и пытается удалить ее еще раз.
Попробуй передавать в — new TForm(Application) чего-нибудь другое или при удалении формы присвой Form1=NULL.
** pasha
Отправлено: 01.07.2004, 11:06


Не зарегистрирован







toAVC

Попробовал, переделал под Bpl с динамической загрузкой
(LoadPackage)
Теперь программа отвечает:
"Application is not licensed to use this feature"
после загрузки пакета при попытке вызова функции из
пакета.

А как описывать вызываемые функции и их типы ?
(и в BPL и в EXE ?)

Как
extern "C" void __declspec(dllexport) PackageSay(char *WhatToSay);
или
extern PACKAGE void PackageSay(char *WhatToSay);
и как описать их тип в typedef
AVC
Отправлено: 01.07.2004, 11:27


Ветеран

Группа: Модератор
Сообщений: 1583



При статической загрузке (меньше всего головной боли)
в exe:
extern PACKAGE AnsiString Value1;
extern PACKAGE void __fastcall Fun1 (...);

в пакете
PACKAGE AnsiString Value1;
PACKAGE void __fastcall Fun1 (...)
{...}

Вызов из exe или других пакетов
Value1 = "aaa"; Fun1();

При динамической загрузке
так же как и при работе с dll
поиск адреса по имени и косвенный вызов
int funadr = (int)GetProcAddress((HMODULE)lbm->instance, funname.c_str());
if (bpl) ((void __fastcall (*)(void))funadr)();
if(dll) ((void __stdcall (*)(void))funadr)();

Кусок кода сдесь

User Attached Image Скачать файл
LEUP.txt


** pasha
Отправлено: 01.07.2004, 11:43


Не зарегистрирован







Нужна только динамическая загрузка.
Как я понял, в этом случае используется
extern "C" void __declspec(dllexport) PackageSay(char *WhatToSay);
и в пакете и в exe, а не PACKAGE ?


AVC
Отправлено: 01.07.2004, 11:58


Ветеран

Группа: Модератор
Сообщений: 1583



Смотрите пример там есть все, что я хотел сказать.

Без Package
Описание в пакете:
extern "C" __declspec(dllexport) void CTB_Correct (void);
void CTB_Correct (void) { ... }

Использование:
try { LEUP_void ("_CTB_Correct", "TBCOR.DLL"); }
catch (Exception &xcp) { ShowMessage(xcp.Message); }

** pasha
Отправлено: 01.07.2004, 12:05


Не зарегистрирован







Так вот я так и пробовал — он пишет:
"Application is not licensed to use this feature"
после загрузки пакета при попытке вызова функции из пакета
AVC
Отправлено: 01.07.2004, 12:07


Ветеран

Группа: Модератор
Сообщений: 1583



Проверьте параметр пакета DesignTime / RunTime

Отредактировано AVC — 01/07/2004, 12:09
** pasha
Отправлено: 01.07.2004, 12:25


Не зарегистрирован







Проверил — стояло Runtime and Design
Поставил только Runtime — тоже самое сообщение.

Я использую сторонние компоненты в форме, создаваемой DLL
(EhLib, RxLib, FIBPlus, FastReport)
может это в них что-то встроено ?

Кстати, если ставлю галочку в Build With Runtime Packages -
то работает, без этой галочки — увы.
(да и работает так-же криво как и dll — дает ошибку при завершении
приложения)

Но мне то нужно, чтобы мои bpl подгружались динамически,
а стандартные bpl — входили в exe
AVC
Отправлено: 01.07.2004, 12:39


Ветеран

Группа: Модератор
Сообщений: 1583



Я с таким сталкивался на ворованом FastReport. Помогло включение FastReport как runtime bpl.
QUOTE

Но мне то нужно, чтобы мои bpl подгружались динамически,
а стандартные bpl — входили в exe

Укажите в перечне, только то что вам нужно.

PS.
Под динмическими bpl я понимал не те которыми управляет Borland (при включении галочки Runtime packages) а те которыми управляю я через Load/Unload. С моей точки зрения галочку Borlanda надо бы назвать External packages
** pasha
Отправлено: 01.07.2004, 12:57


Не зарегистрирован







FastReport и FIBplus у меня законные, купленные smile.gif
RxLib + EhLib вроде как бесплатные, других сторонних
компонентов в этих формах не использовал.

Ладно, придется оставлять в виде dll + borlndmm.dll + cc3260mt.dll
прикладываеть к проекту, так работает и работает без ошибок.

Вернуться в Вопросы программирования в C++Builder