Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.04.24;
Скачать: [xml.tar.bz2];

Вниз

Помогите создать кнопку при помощи DLL.   Найти похожие ветки 

 
acsoft   (2003-04-09 07:55) [0]

Может кто-нибудь поможет с написанием программы, которая вызывала бы DLL, создающую кнопку в окне программы.

Подобная конструкция постоянно вызывает ошибку:

library Project2;
uses
Windows, SysUtils, Classes, Controls, Forms, StdCtrls;

{$R *.RES}

function CallPlugin(parent:TForm):boolean; stdcall;
var
Newbut:TButton;
begin
newbut:=tbutton.Create(parent);
newbut.parent:=parent;
newbut.Visible:=true;
result:=true;
end;

exports
CallPlugin;
end.

{------------}

procedure TForm1.Button1Click(Sender: TObject);
var
LibHandle: THandle;
CallPlugin: function(parent:TForm):boolean;
begin
LibHandle:=loadlibrary("project2.dll");
if LibHandle >= 32 then begin
CallPlugin:= GetProcAddress(LibHandle,"CallPlugin");
CallPlugin(form1);
end;
FreeLibrary(LibHandle);
end;


 
sniknik   (2003-04-09 08:18) [1]

скорее всего изз этого
uses
ShareMem, Windows, SysUtils, Classes, Controls, Forms, StdCtrls;

в программе тоже должен стоять первым.


 
evvcom   (2003-04-09 08:37) [2]

Я думаю, дело в том, что кнопка создается в dll, поэтому код класса TButton также лежит в этой dll. После создания объекта все вызовы методов класса идут в адресное пространство dll. Ну а после FreeLibrary, например, уже перерисовка кнопки будет вызывать Access Violation. Т.е. вся заморочка здесь в том, что TButton exe-файла и TButton dll-файла - это совершенно разные классы с точки зрения размещения кода в памяти! И об этом не стоит забывать.
Самый простой выход здесь - это не освобождать библиотеку пока нужна еще кнопка. Перед освобождением dll естественно разрушить объект кнопки.
Если же все же нужна кнопка именно таким способом, (т.е. чтобы она могла существовать без dll), то грамотное решение здесь трудно отыскать. Например, если передавать в dll ссылку на класс TButton (класс в exe, это я не пробовал, поэтому если это не удастся прошу меня не винить), то в этом случае, чтобы работать в dll с этим классом, этот класс должен иметь точно такую же структуру класса, что и в exe-файле, а это возможно только при одинаковой версии классов exe и dll, т.е. в данном случае только при одной версии Delphi, а это сразу сводит весь смысл использования такого кода как dll. (И использование директивы stdcall в данном случае вообще не имеет смысла, все равно эту dll больше никто не сможет корректно вызвать)
А вот грамотное решение придумал. Проще тогда, наверное, передавать в dll адрес простой функции типа procedure CreateButton; находящуюся в exe-файле. Тогда все будет корректно и работать с такой dll можно будет из любого места.


 
Fantasist.   (2003-04-11 02:02) [3]


> После создания объекта все вызовы методов класса идут в
> адресное пространство dll


Для справедливо только для виртуальных и динамических методов.

Так же нужно отметить, что чаще всего выделять память в длл и освобождать ее в ехе (или наоборот) будет приводить к ошибке, так как менеджеры памяти у длл и ехе разные.


 
evvcom   (2003-04-11 14:40) [4]

> Для справедливо только для виртуальных и динамических методов.
Не согласен. Хотя и я не совсем, наверное, прав в этой фразе.

> Так же нужно отметить, что чаще всего выделять память в длл и освобождать ее в ехе (или наоборот) будет приводить к ошибке, так как менеджеры памяти у длл и ехе разные.
И опять не согласен. Не буду говорить про New и всякие дельфовые AllocMem - не пробовал. А пробовал я с выделением памяти в куче процесса через API - никаких проблем (GetProcessHeap, HeapAlloc, HeapFree).


 
Fantasist.   (2003-04-11 17:27) [5]


> Не согласен. Хотя и я не совсем, наверное, прав в этой фразе


И напрасно. Компилятор в коде подставляя вызовы методов выбирает их на основании типа переменной. То есть, если он видит а.Method1, где а:ClassA, то он подставит вызов ClassA.Method1, а где находиться адресс этого метода ему прекрасно известно, так как он сам его и скомпилировал. И только для всяких видов виртуальных методов, поиск адреса метода осуществляется в таблице, а указатель на эту таблицу как раз берется у конкретного экземпляра класса. (то есть примерно a._vmt^+(offset to Method1) где _vmt - указатель на vmt, и значение его задается конструктором).


> А пробовал я с выделением памяти в куче процесса через
> API - никаких проблем (GetProcessHeap, HeapAlloc, HeapFree).


Есстественно, тут менеджером памяти выступает кернел, а он один и оперирует со своей областью памяти. Я же говорил про стандартное выделение памяти, в частности про GetMem, которая используется Delphi при создании экземпляров класса. Эти операции производятся делфийским менеджером памати.


 
BigDAN   (2003-04-14 09:34) [6]

Если прогу и библиотеку откомпилить с галкой Build with runtime packages - проблема будет решена. Вот только прогу надо будет распространять с соответствющими bpl-ками



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.04.24;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.009 c
1-77008
esprit_bel
2003-04-14 07:08
2003.04.24
сортировка


1-76889
Rule
2003-04-14 03:00
2003.04.24
QReport конвертировать в MSWord


1-76875
Silver_
2003-04-14 16:09
2003.04.24
типа Screen.OnActiveControlChange


3-76838
Remis
2003-04-05 00:15
2003.04.24
сортировка по национальному альфабиту


4-77239
Anonimus
2003-02-27 09:59
2003.04.24
Скажите плиз где взять пример работы с MS Agentом на Дельфи???





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