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

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.45 MB
Время: 0.007 c
1-57758
Андре_
2002-04-01 09:49
2002.04.18
Сборщик мусора


3-57599
Vlad_Leon
2002-03-27 09:13
2002.04.18
Как узнать пароль?


6-57829
Брыкун Дмитрий
2002-02-06 14:50
2002.04.18
Как написать письмо?


14-57882
Cyberbob
2002-03-10 15:45
2002.04.18
Как мне создать такую базу и где?????


1-57754
voland0
2002-04-05 12:37
2002.04.18
Помогите!!! onStartDrag в TDBGrid не наступает!!!





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