-
Доброго времени суток. Есть программа на Delphi6 для работы с MSSQL7 с помощью SDAC. Необходимо подключить к ней форму с Query и DBGrid, но чтобы форма была в dll и эта dll использовала то же соединение. С написанием dll особо не сталкивался.
Делаю так: Создаю dll проект
uses SysUtils, Classes, Forms, DB, DBAccess, MSAccess, Myform in 'Myform.pas' {Form1};
{$R *.res}
procedure RunMyForm(HouseId:Integer; MyConnection: TMSConnection); cdecl; begin Form1 := TForm1.Create(HouseId, MyConnection, Application); Form1.ShowModal; Form1.Free; end;
exports RunMyForm;
begin end;
и форму.На ней DBGrid1, MSQuery1, MSDataSource1, ну и кнопка.
type TForm1 = class(TForm) Label1: TLabel; Button1: TButton; MSQuery1: TMSQuery; MSDataSource1: TMSDataSource; DBGrid1: TDBGrid; procedure Button1Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public { Public declarations } HouseId:integer; MyConnection: TMSConnection; Constructor Create(AHouseID:integer; AMyConnection: TMSConnection; AOwner : TComponent);reintroduce; end;
var Form1: TForm1;
implementation
{$R *.dfm}
Constructor TForm1.Create(AHouseID:integer; AMyConnection: TMSConnection; AOwner : TComponent); begin inherited Create(AOwner); MyConnection:= AMyConnection; HouseId:=AHouseID; end;
procedure TForm1.Button1Click(Sender: TObject); begin MSQuery1.Connection:=MyConnection; MSQuery1.Open; end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin if MSQuery1.Active then MSQuery1.Close; end;
end.
Для вызова пробывал 2 варианта 1.Статический. type TForm1 = class(TForm) Button1: TButton; MSConnection1: TMSConnection; MSQuery1: TMSQuery; MSDataSource1: TMSDataSource; DBGrid1: TDBGrid; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm} procedure RunMyForm(HouseID:integer; MyConnection:TMSConnection); cdecl; external 'Mydll.DLL';
procedure TForm1.Button1Click(Sender: TObject); begin RunMyForm(1,MSConnection1); end;
end. 2.Динамический. type TForm1 = class(TForm) Button1: TButton; MSConnection1: TMSConnection; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); type TDLLProc = procedure(AHouseId:Integer; AMyConnection:TMSConnection); var MyHandle : THandle; MyProc : TDLLProc; HouseId:Integer; begin HouseId:=1; MyHandle:=LoadLibrary('D:\Work\MyDLL\MyDLL.dll'); if MyHandle>=32 then { if <=32 - error ! } begin @MyProc:=GetProcAddress(MyHandle,'RunMyForm'); if @MyProc<>nil then begin MyProc(1, Form1.MSConnection1); end else ShowMessage('Функция не найдена!'); try FreeLibrary(MyHandle); except end; end else ShowMessage('Библиотека не найдена!'); end;
Так вот при нажатии на Button1 в первом случае все работает, а во втором
Access violation at address 0116F24D in module 'MyDLL.dll'. Read of address 8BD88B97.
А хотелось бы динамически загружать библиотеку. Как это сделать и можно ли так и где я не прав?
Заранее благодарен за ответ.
-
Во 2-м случае беспардонно нарушено соглашение о вызове. Да и вообще лучше выкинуть эту блажь из головы - выносить дельфийскую форму в DLL.
-
Тогда так: 1. А как правильно оформить соглашение о вызове? 2. Про блажь ничего не могу сказать. Задача такая поставлена и не я принимаю решения.
-
> А как правильно оформить соглашение о вызове?
А как ты его оформлял при статике ? Точно так же и при динамике - суть-то от этого не меняется .. Или ты "намекаешь" на то что не понимаешь, о каких таких "соглашениях" идет речь ? Ну тогда тебе в "Сад", а не в "Базы" ...
> Про блажь ничего не могу сказать. Задача такая поставлена и не я принимаю решения
Это печально. Очень. Особенно с учетом того что за исполнение задачи взялся человек, привыкший бездумно копипастить шматки кода, невесть откуда выдранные из Тырнета.
Али возражения будут, мол, все было совсем не так ?)
-
Спасибо за помощь.
|