![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
DLLCHILD...
memo © (2006-09-28 11:28:00)Здравствуйте!
У меня такой вопрос (Даже скорей проблема):
"Я создал внутри DLL, форму , пример процедур видно ниже. Cама DLL компилируется отлично... Не каких проблем...-->
procedure InitPlugin(App, Scr: integer); StdCall;
begin
DLLScr:= Screen;
Screen:= TScreen(Scr);
DLLApp:= Application;
Application:= TApplication(App);
end;
procedure DonePlugin; StdCall;
begin
Screen:= DLLScr;
Application:= DLLApp;
end;
function CreateCardMDI: integer; StdCall;
begin
Result:= integer(TCardForm.Create(Application))
end;
exports
InitPlugin,
DonePlugin,
CreateCardMDI;
--> ...А вот с вызовом этой формы из DLL, у меня возникли проблемы..."
А в частности меня интересует динамическая загрузка...
Ниже код вызова формы из DLL (Не получается.... :o( ):
procedure TMainForm.Buttom1Click(Sender: TObject);
var
CardHandle: THandle;
begin
CardHandle:= LoadLibrary('dll\Card\dCardMDI.dll');
GetProcAddress(CardHandle,'InitPlugin');
InitPlugin(integer(Application), integer(Screen));
GetProcAddress(CardHandle,'CreateCardMDI');
CreateCardMDI;
GetProcAddress(CardHandle,'DonePlugin');
DonePlugin;
FreeLibrary(CardHandle);
end;
ВОПРОС:
"Что я делаю не так..???"
И если можно, то конкретно подчеркнуть мои ошибки...
Заранее благодарен! Memo.
Ketmar (2006-09-28 13:38:00) [1]>[11] clickmaker(c) 28-Sep-2006, 13:33
>одним но. И экзе и dll должны быть собраны с
>одними run-time vcl пакетами
или с ShareMem. или с его аналогами. %-)
clickmaker (2006-09-28 13:33:00) [2]
> [9] Amoeba © (28.09.06 13:19)
давно уже такая технология отлажена и работает. С одним но. И экзе и dll должны быть собраны с одними run-time vcl пакетами
Ketmar (2006-09-28 13:22:00) [3]>[9] Amoeba(c) 28-Sep-2006, 13:19
>Только вот передавать в DLL объекты из
>основной программы или использовать в основной
>программе объекты создаваемые в DLL нельзя
???
Amoeba (2006-09-28 13:19:00) [4]
> memo (28.09.06 12:04) [7]
> Да еще вопрос...
> Могу ли я на "Форму DLL", поместить ADOConntction1 , таблиц
> , квериков...
> и тем самым вызывать форму из длл , как какогота к примеру
> клиента MSSQL?
> В обще магу ли я имея форму в ДЛЛ, работать с БД???
Можешь. Только вот передавать в DLL объекты из основной программы или использовать в основной программе объекты создаваемые в DLL нельзя, т.к. если даже как бы и будет работать, но но все равно возникнут неразрешимые проблемы.
clickmaker (2006-09-28 12:08:00) [5]
> [6] memo (28.09.06 11:56)
я ж написал, как ее надо вызывать...
memo (2006-09-28 12:04:00) [6]Да еще вопрос...
Могу ли я на "Форму DLL", поместить ADOConntction1 , таблиц , квериков...
и тем самым вызывать форму из длл , как какогота к примеру клиента MSSQL?
В обще магу ли я имея форму в ДЛЛ, работать с БД???
memo (2006-09-28 11:56:00) [7]
> clickmaker © (28.09.06 11:42) [2]
Ругается... Типа:
"Не хочу компилировать! У вас необявлена процедура InitPlugin(integer(Application), integer(Screen));"
А я вот голову ломаю на... хренна ее объевлять, если я получаю на нее укозатель и вызываю вообще из ДЛЛ... :o(
Не пойму структуры вызова и обработки DLL-ных... процедур и функций...
:o/
alles (2006-09-28 11:53:00) [8]взято и Кулибы
Я сделал так - выбираю все DLL из каталога с программой, загружаю каждую и пытаюсь найти в ней функцию (через API GetProcAddress) с заранее определенным жестко именем (например что нибудь типа IsPluginForMyStuff). Если нашлась - DLL считается моим плагином, если нет - выгрузить и забыть.
А набор вызываемых функций по идее одинаков у всех плагинов, и программа (основная) в курсе какие именно функции она ищет в DLL. Если даже и не так, то ничего не мешает тебе определить в плагине функцию наподобие GetFeatures, возвращающую список строк-названий поддержанных плагином процедур.
Вот часть моего кода по работе с плагинами...
--------------------------------------------------------------------------------
...
type
// Процедурные типы для хранения ссылок на функции плагинов
TGetNProc=function:shortstring;
TGetSProc=function:integer;
TProcessProc=procedure(config:pointer; request:PRequest; var reply:PReply);
TConfigProc=procedure(defcfg:PSysConfig; var config:pointer);
TSaveLoadProc=procedure(inifile:pointer; var config:pointer);
// Информация об отдельном плагине
TPlugin=record
Name:shortstring; // Полное название
Filename:shortstring; // Имя файла
Handle:integer; // Хэндл загруженной DLL
CFGSize:integer; // Размер конфигурации в RAM
ProcessProc: TProcessProc; // Адрес процедуры обработки
ConfigProc: TConfigProc; // Адрес процедуры настройки
LoadCFG,SaveCFG:TSaveLoadProc; // Адреса процедур чтения/записи cfg
end;
PPlugin=^TPlugin;
// Список загруженных плагинов
TPlugins=class(TList);
...
var
Plugins:TPlugins; sr:TSearchRec; lib:integer;
pgetn:TGetNProc; pgets: TGetSProc; plugin:PPlugin;
...
// Читаем плагины и создаем их список.
Plugins:=TPlugins.Create;
if FindFirst('*.dll',faAnyFile,sr)<>0 then begin
ShowMessage('Hе найдено подключаемых модулей.');
Close;
end;
repeat
lib:=LoadLibrary(PChar(sr.Name));
if lib<>0 then begin
@pgetn:=GetProcAddress(lib, 'GetPluginName');
if @pgetn=nil then FreeLibrary(lib) // Hе плагин
else begin
New(plugin);
@pgets:=GetProcAddress(lib, 'GetCFGSize');
plugin.Name:=pgetn;
plugin.Filename:=sr.Name;
plugin.CFGSize:=pgets;
plugin.Handle:=lib;
plugin.ConfigProc:=GetProcAddress(lib, 'Configure');
plugin.ProcessProc:=GetProcAddress(lib, 'Process');
plugin.SaveCFG:=GetProcAddress(lib, 'SaveCFG');
plugin.LoadCFG:=GetProcAddress(lib, 'LoadCFG');
Plugins.Add(plugin);
end;
end;
until FindNext(sr)<>0;
FindClose(sr);
clickmaker (2006-09-28 11:53:00) [9]type
TInitPlugin = procedure(App, Scr: integer); StdCall;
var
p: TInitPlugin;
@p = GetProcAddress;
p(Application, Screen);
memo (2006-09-28 11:51:00) [10]Хорошо, вот к примеру...
type
TDllfunc = function: TDllobjectClass;
stdcall;
Функцию объявил....
......
@fDllfunc := GetProcAddress(fHandle, 'Dllfunc');
......
Получил указатель.... Далее по коду вызвал...
if Assigned(@fDllfunc) then....
А вот как объявить процедуры...?
Скока вариантов и примеров не пробовал, не получается...
Ктобы мог расписать правельно код, в моём случае...???
clickmaker (2006-09-28 11:42:00) [11]
> Ниже код вызова формы из DLL (Не получается.... :o( ):
что именно не получается?
PS. Преобразования к integer - лишние. Там и так 4-байтовые указатели
alles (2006-09-28 11:40:00) [12]procedure TMainForm.Buttom1Click(Sender: TObject);
var
CardHandle: THandle;
begin
CardHandle:= LoadLibrary('dll\Card\dCardMDI.dll');
if CardHandle=0 then exit;
GetProcAddress(CardHandle,'InitPlugin');
InitPlugin(integer(Application), integer(Screen));
GetProcAddress(CardHandle,'CreateCardMDI');
CreateCardMDI; как обьявил эту проц.?
GetProcAddress(CardHandle,'DonePlugin');
DonePlugin; как обьявил эту проц.?
FreeLibrary(CardHandle);
end;