![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
bpl дебаг [D6, Win2k]
alienserg © (2004-07-06 19:19:00)Столкнулся со странной проблемой, может кто чего посоветует или прояснит.
Имеется простой тестовый плагин в виде BPL(simplePlugin.bpl).
Он динамически подгружается с помощью LoadPackage
Плагин включает в себя класс, являющийся наследником класса-шаблона, описанного в другом package(plugIt.bpl). Вот фрагмент из plugIt:
type
TCallbackProc = procedure(msgBody:string) of object;
TBplPlugin = class
public
procedure StartModule(ACallback: TCallbackProc); virtual; abstract;
procedure MessageProcess(const s:string); virtual; abstract;
class function GetVersion: string; virtual; abstract;
class function GetModID: integer; virtual; abstract;
end;
В случае простого хостового приложения плагин загружается, закрытие приложения происходит штатно, код внутри плагина можно дебагить с помощью брейкпойнтов.
Если же я подключаю этот плагин к реальному хостовому приложению, то плагин нормально загружается и функционирует, Но при закрытии приложения выдается AV. Если запущено в режиме дебага, то при закрытии приложения вываливается окно CPU debug. При этом код внутри плагина недоступен для дебага, брейкпойнты остаются задизейблеными в виде красной точки с зеленым крестиком. С другой стороны проставленные в брейкпойнтахShowMessage('bpl hell');срабатывают успешно.
Что может быть причиной невозможности отладки BPL? О чем это может говорить? Модули simplePlugin.bpl и plugIt.bpl совершенно идентичны в первом и втором случае, я их копирую. Хостовые приложения имеют plugIt в списке Runtime Packages.
Схема подключения плагина следущая.
в каждом плагине есть класс-наследник класса шаблона, например
TSFBplPlugin = class(TBplPlugin)
public
//filename: string;
procedure StartModule(ACallback: TCallbackProc); override;
procedure MessageProcess(const s:string); override;
class function GetVersion: string; override;
class function GetModID: integer; override;
end;
в каждом плагине есть секция инициализации(наименование TSFBplPlugin естественно варьируется от плагина к плагину):
initialization
ClassManager.Add(TSFBplPlugin);
Этот код добавляет класс TSFBplPlugin в TList(ClassManager)
Код вызова также совершенно идентичен:
procedure TmainForm.Button1Click(Sender: TObject);
var
pluginClass: TClass;
plugin: TBplPlugin;
begin
//грузим плагин и код его инициализации добавляет класс TSFBplPlugin в ClassManager
LoadPackage(ExtractFilePath(ParamStr(0)) + 'simplePlugin.bpl');
//берем только что добавленный класс(я знаю, что в моем случае он первый в списке - это тест)
pluginClass:= ClassManager[0];
//создаем экземпляр плагина
plugin:= TBplPlugin(pluginClass.Create);
//запускаем плагин(создаем форму, передаем адрес callback функции и т.д.)
plugin.StartModule(ProcessResponse);
end;
Но мне кажется, что дело не в некорректности подключения плагина, а в чем-то ином. О чем говорит тот факт, что я не могу зайти дебагом в код плагина?
Пользую Delphi6 без апдейтов.
alienserg (2004-07-06 20:48:00) [1]финализация в плагине тоже есть:
initialization
ClassManager.Add(TSFBplPlugin);
finalization
ClassManager.Remove(TSFBplPlugin);
Схема проверки плагина предельно простая: в Run>>Parameters указываю хостовое приложение, в самом плагине устанавливаю обработчик нажатия кнопки:
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('bpl hell');
end;
Ставлю брейкпойнт на строке ShowMessage.
Запускаю отладку.
Загружается хостовое приложение.
Нажатием кнопки гружу плагин вышеописанным методом.
Стартую плагин вызовом
plugin.StartModule(ProcessResponse);
передавая этим адрес callback функции.
StartModule создает форму и показывает ее. Больше ничего не делает. Жму на кнопку, где брейкпойнт, но там не останавливается а просто по ShowMessage выскакивает диалоговое окно с текстом.
Основной вопрос, который меня волнует - почему я не могу дойти до отладки в плагине в случае, если хостовое приложение - мое навороченное. Если хостовое - простое тестовое, то все протекает как надо, отлаживаюсь, закрываюсь без AV. Код загрузки и старта плагина совершенно идентичен в обоих случаях.
wisekaa (2004-07-06 19:45:00) [2]Судя из выше перечисленного ошибка вылетает не в плугине, а в хостовом приложении.
Зделай в плугине деинициализацию, которая вызываеться на выгрузку, и если AV возникает после, то что-то не корректно реализовано, в главном приложении, скорее всего работа с общими ресурсами, т.е. объект принадлежит плугину, при его выгрузке уничтожаеться, а в главном приложении есть на него ссылка, по которой происходит обращение к уже не сущест. объекту