** 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 тоже ? |
Для начала можно только в ехе
|
|
** 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 библиотеки, да возможно
что где-то это и по-другому сглючит. |
|
** 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)();
Кусок кода сдесь
|
|
** 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 у меня законные, купленные
RxLib + EhLib вроде как бесплатные, других сторонних
компонентов в этих формах не использовал.
Ладно, придется оставлять в виде dll + borlndmm.dll + cc3260mt.dll
прикладываеть к проекту, так работает и работает без ошибок. |
|