Вниз
Скачать: 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 вся ветка

Скачать: CL | DM;



Память: 0.45 MB
Время: 0.008 c
7-57902
777
2002-01-23 08:44
2002.04.18
Модем в он-лайне?


4-57911
xpyctuk
2002-02-14 13:06
2002.04.18
Как вытащить выделенный фрагмент текста с других приложений


3-57611
bill133
2002-03-22 23:23
2002.04.18
Какая БД лучше


1-57741
ymin
2002-04-05 12:15
2002.04.18
Кстати а можно ли записать данные допустим в таблице EXCEL


1-57778
Zool
2002-04-05 16:34
2002.04.18
_FileTime




   Наверх