Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.04.18;
Скачать: CL | DM;

Вниз

Interface и указатель   Найти похожие ветки 

 
Dimka Maslov ©   (2002-04-04 11:05) [6]

если ты предпочитаешь, чтобы все было под твоим контролем - ты создаёшь объект, ты его и уничтожаю, когда тебе этого захочется, то наследуй объект, реализующий интерфейс не от TInterfacedObject, а от TObject, и твой код должен выглядеть так

IMyInterface=interface
["{2D67E340-4705-11D6-A1F0-444553540000}"]
function Funct:integer;
end;

TMyClass=class(TObject, IMyInterface)
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function Funct:integer;
end;

function TMyClass._AddRef: Integer;
begin
Result:=-1;
end;

function TMyClass._Release: Integer;
begin
Result:=-1;
end;

function TMyClass.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then Result:=S_OK else Result:=E_NOINTERFACE;
end;

function TMyClass.Funct;
begin
Result:=3;
end;

function TForm1.Button1Click(Sender: TObject);
var
Obj: TMyClass;
Ifc: IMyInterface;
begin
Obj:=TMyClass.Create;
try
Obj.GetInterface(IMyInterface, Ifc);

// Делаешь все что захочешь с Ifc, но всё равно вызывать Ifc._Release не надо

finally
Obj.Free;
end;
end;


А теперь разберёмся понятиями "переменная процедурного типа" "указатель на интерфейс" и просто "указатель".

Как известно, указатель есть переменная содержая адрес ячейки памяти, безотносительно тому, что содержится в этой ячейке.

Переменная процедурного типа - тоже указатель, но указывает он на точку входа в конкретную процедуру.

Указатель на интерфейс - есть указатель на таблицу методов интерфейса, перым членом которой является указатель на метод QueryInterface.

Разберёмся теперь с почему не работает твой первый пример и работает второй...

procedure TForm1.Button1Click(Sender: TObject);
var
cl:TMyClass;
p,p1:pointer;
begin
cl:=TMyClass.Create;
// Создание объекта
cl.GetInterface(IMyInterface, p);
// получение указателя на интерфейс и запись его в нетипизированный указатель.
QI:=p;
// связывание переменной продедурного типа с нетипизированным указателем, указывающим на таблицу методов, первым из которых стоит метод function (Self: IMyInterface; const IID: TGUID; out Obj): HResult stdcall; ты же присваиваешь адрес этой процедуры переменной, которая ссылается на процедуру function (IID: TGUID; out Obj): LongInt register;. Имеющую разные аргументы и разный формат вызова, что неминуемо приведет к ошибке при вызове такой процедуры через указатель...
QI(IMyInterface,p1); //Invalid pointer operation
// что и происходит
cl._Release;
end;

Во втором случае ты связываешь procedure с procedure по этому всё работает.



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

Текущий архив: 2002.04.18;
Скачать: CL | DM;

Наверх




Память: 0.47 MB
Время: 0.017 c
1-57715
Tiomik
2002-04-08 12:39
2002.04.18
какие книги посоветуете начинающему програмисту???


3-57636
koks
2002-03-26 13:45
2002.04.18
ADO -> Access 2000 ???? HEEEEEEEEELP !


1-57815
Дима2
2002-04-01 18:49
2002.04.18
DialogSave


1-57761
Avgurin
2002-04-05 17:17
2002.04.18
Как копировать файлы попроще (глупо да?) я - новичок


3-57662
Pupsik
2002-03-29 08:08
2002.04.18
ADO и Jet update