Форум: "Основная";
Текущий архив: 2004.07.18;
Скачать: [xml.tar.bz2];
ВнизКак передать TGraphic из DLL в программу Найти похожие ветки
← →
killer © (2004-06-27 03:04) [0]Как можно передать TGraphic из DLL в программу?
я делаю так, но вылитает ошибка постоянно...
в форме DLL:
function ShowFormView(Handle: HWnd; Img: TGraphic): TGraphic; stdcall;
var
Form1: TForm1;
begin
Application.Handle:=Handle;
Form1:=TForm1.Create(Application);
Form1.Image1.Picture.Graphic:=Img;
Form1.ShowModal;
Result:=Form1.Image1.Picture.Graphic;
Form1.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenPictureDialog1.Execute then
begin
Image1.Picture.Graphic.LoadFromFile(OpenPictureDialog1.FileName);
end;
end;
в программе:
procedure TForm1.BitBtn2Click(Sender: TObject);
var
View: LongWord;
ShowFormView: function(Handle: HWnd; Img: TGraphic): TGraphic; stdcall;
begin
View:=LoadLibrary("View.dll");
if View=0 then
begin
Application.MessageBox("The library View.dll is not found.", "Error", mb_IconStop+mb_Ok);
end
else
begin
@ShowFormView:=GetProcAddress(View,"ShowFormView");
Image1.Picture.Graphic:=ShowFormView(Application.Handle, Image1.Picture.Graphic);
FreeLibrary(View);
end;
end;
Помогите пожалуйста...
← →
Vitalik (2004-06-27 11:13) [1]Ну почему так происходит - могу сказать. Как исправлять - только предположения.
Происходит из-за того, что ты работаешь в двумя программами, и у каждой своя область памяти, которые никак не пересекаются. Одна прога - это твой exe-файл, а другая - dll. В exe у тебя находится в памяти объект TGraphic и на него ссылается четырёхбайтовый указатель - Image1.Picture.Graphic. Вот эти 4 байта ты и передаёшь в библиотеку. В библиотеке они успешно принимаются и строка
Form1.Image1.Picture.Graphic:=Img;
устанавливает свой указатель, на тот же адрес, но уже в своей области памяти. А что может находится в памяти библиотеки по данному адресу? Да всё, что угодно, но только не то что тебе нужно! А тебе нужен объект TGraphic.
Такая фишка, кстати, имеет место быть и в случае, когда ты передаёшь в DLL длинные строки, которые тоже являются указателями. Вообще, если ты передаёшь в DLL указатель, то ты должен всегда об этом помнить! И понимать, что в DLL указателю указывать как бы и не на что :)
Ну а выход - использовать диспетчер памяти из модуля ShareMem. Но тут я тебе уже не помошник, т.к. я в этом вопросе чистый теоретик :)
Кстати, когда ты делаешь в Delphi "File->New->Other..." и выбираешь "DLL Wizard" то в новом файле автоматически пишется комментарий про использование ShareMem...
← →
killer © (2004-06-27 17:03) [2]Добавил я модуль ShareMem и в программу и в форму DLL... теперь в фоме DLL при открытии изображения возникает, и ничего не открывается...
← →
killer © (2004-06-27 17:07) [3]Удалено модератором
← →
killer © (2004-06-27 23:40) [4]Может через поток какнибудь???
← →
VMcL © (2004-06-27 23:56) [5]>>Vitalik (27.06.04 11:13) [1]
>Происходит из-за того, что ты работаешь в двумя программами, и у каждой своя область памяти, которые никак не пересекаются. Одна прога - это твой exe-файл, а другая - dll.
Это что-то новое в Win32.
>>killer © (27.06.04 03:04)
Используй packages (BPL).
← →
killer © (2004-06-27 23:58) [6]Нужно DLL...
← →
KilkennyCat © (2004-06-28 00:18) [7]ну ежели обмениваться памятью, то полезно про мьютексы почитать...
← →
killer © (2004-06-28 01:11) [8]KilkennyCat Это в книге по програмированию??? Что-то нету тут... :(
← →
KilkennyCat © (2004-06-28 01:30) [9]Image1.Picture.Graphic:=ShowFormView(Application.Handle, Image1.Picture.Graphic);
а почему так?
Может, стоит попробовать так:
http://www.delphimaster.ru/articles/usedll/index.html
пример 2
← →
killer (2004-06-28 01:40) [10]А у меня не так же? :)
← →
KilkennyCat © (2004-06-28 01:46) [11]а хэндл?
← →
KilkennyCat © (2004-06-28 01:48) [12]а блин, че-то я вообще запутался :)
← →
killer © (2004-06-28 01:49) [13]Это для того, чтобы форма, которая в DLL, чтобы не выводилась на панели задачь в отдельном окне...
← →
killer © (2004-06-28 01:50) [14]я думаю от этого хендла ничего не зависит...
← →
killer © (2004-06-28 07:02) [15]Что-то у меня до сих пор ничего не получается........ :((
← →
KilkennyCat © (2004-06-28 07:38) [16]
> killer © (28.06.04 07:02) [15]
я вечером освобожусь - попробую.
← →
killer © (2004-06-28 08:12) [17]KilkennyCat Хорошо :)
← →
Digitman © (2004-06-28 08:25) [18]> Result:=Form1.Image1.Picture.Graphic;
> Form1.Free; //здесь наряду с "убийством" формы происходит и "убийство" объекта Graphic, и в результате возвращяется не ссылка на объект, а "мусор"
← →
KilkennyCat © (2004-06-28 08:38) [19]
> Digitman © (28.06.04 08:25) [18]
и действительно...
мда... пойду курить.
← →
killer © (2004-06-28 20:42) [20]точно...... значит наверно никак нельзя передать......
← →
killer © (2004-06-30 02:25) [21]В принципе у меня получилось...
Форма в DLL:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Jpeg, ExtDlgs, StdCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
Button1: TButton;
OpenPictureDialog1: TOpenPictureDialog;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
procedure ShowFormView(Handle: HWnd; var Img: TGraphic); export;
procedure FreeFormView; export;
implementation
{$R *.dfm}
procedure ShowFormView(Handle: HWnd; var Img: TGraphic); export;
begin
Application.Handle:=Handle;
Form1:=TForm1.Create(Application);
Form1.Image1.Picture.Graphic:=Img;
Form1.ShowModal;
Img:=Form1.Image1.Picture.Graphic;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenPictureDialog1.Execute then
begin
Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Close;
end;
procedure FreeFormView; export;
begin
Form1.Free;
end;
end.
Программа:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtDlgs, XPMan, StdCtrls, Buttons, ExtCtrls, Jpeg;
type
TForm1 = class(TForm)
Image1: TImage;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
XPManifest1: TXPManifest;
OpenPictureDialog1: TOpenPictureDialog;
procedure BitBtn1Click(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.BitBtn1Click(Sender: TObject); // Open
begin
if OpenPictureDialog1.Execute then
begin
Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
end;
end;
procedure TForm1.BitBtn2Click(Sender: TObject);
var
View: LongWord;
ShowFormView: procedure(Handle: HWnd; var Img: TGraphic); stdcall;
FreeFormView: procedure; stdcall;
Gr: TGraphic;
begin
View:=LoadLibrary("View.dll");
if View=0 then
begin
Application.MessageBox("The library View.dll is not found.", "Error", mb_IconStop+mb_Ok);
end
else
begin
@ShowFormView:=GetProcAddress(View,"ShowFormView");
@FreeFormView:=GetProcAddress(View,"FreeFormView");
Gr:=TGraphic.Create;
Gr:=Image1.Picture.Graphic;
ShowFormView(Application.Handle, Gr);
Image1.Picture.Graphic:=Gr;
Gr.Free;
FreeFormView;
FreeLibrary(View);
end;
end;
end.
Все передается... Только вот почему-то на функции FreeFormView возникает ошибка. Почему?
← →
Digitman © (2004-06-30 09:10) [22]
> Почему?
потому что в теле ф-ции FreeFormView() происходит обращение к несуществующему уже объекту класса TForm1, ссылка на который осталась в виде "мусора" в переменной Form1
← →
killer © (2004-06-30 14:24) [23]А сама форма в DLL, которая удаляется??? Каким образом, если мы ее не удалили?
← →
killer © (2004-06-30 15:11) [24]Убрал я функцию FreeFormView... теперь еще какая-то ошибка...:(
← →
killer © (2004-06-30 16:54) [25]Help
← →
killer © (2004-07-01 00:43) [26]??? :(((
← →
Гаврила © (2004-07-01 01:25) [27]Блин !!!!
никогда не объявляйте в бибилиотеке параметрами указатели на VCL экхемпляр-класса !!!!
НИКОГДА !
Ни входными, ни выходными
это неправильно
← →
killer © (2004-07-01 02:05) [28]Гаврила Извени... я что-то не очень понял...
← →
killer © (2004-07-01 02:19) [29]Если в программе написать:
ShowFormView(Application.Handle, Image1.Picture.Graphic);
не компилируется... пишет что этот параметр только для чтения... и что делать?
← →
killer © (2004-07-01 17:16) [30]Может сделать форму DLL которая модулем... и не париться...?
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.07.18;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.027 c