Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.01.2013, 09:48   #1
LISTAT
Пользователь
 
Регистрация: 27.10.2011
Сообщений: 50
По умолчанию Получить по ссылке на интерфейс указатель на класс в котором он реализован

Доброго времени суток.
Есть у меня задача, которая связана с использованием интерфейсов. Реализовывают интерфейсы разные классы. Вопрос в том, как имея ссылку на интерфейс получить указатель на класс в котром он реализован и вызвать метод Free.
Пока делаю это, описывая интерфейсную функцию
Код:
function GetPointObject:TObject;stdcall;
Реализация этой функции следующая
Код:
function <CLASS>.GetPointObject:TObject;
begin
    result:=Self;
end;
Да это работает, но хотелось бы просто получив ссылку на интерфейс выйти на класс и вызвать его деструктор.
Еще нагуглил такой код, который предположительно возвращает указатель на класс по ссылке на интерфейс, проверял - работает, но как-то не внушает доверия.

Код:
function GetImplementingObject(const I: IInterface): TObject;
const  
  AddByte = $04244483; 
  AddLong = $04244481; 
 
type  
  PAdjustSelfThunk = ^TAdjustSelfThunk;
  TAdjustSelfThunk = packed record    
    case AddInstruction: longint of      
      AddByte : (AdjustmentByte: shortint);      
      AddLong : (AdjustmentLong: longint);  
    end;  
  PInterfaceMT = ^TInterfaceMT;  
  TInterfaceMT = packed record    
    QueryInterfaceThunk: PAdjustSelfThunk;  
  end;  
  TInterfaceRef = ^PInterfaceMT;
 
var  
  QueryInterfaceThunk: PAdjustSelfThunk;
begin  
  Result := Pointer(I);  
  if Assigned(Result) then
  try      
    QueryInterfaceThunk := TInterfaceRef(I)^.QueryInterfaceThunk;      
    case QueryInterfaceThunk.AddInstruction of        
      AddByte: Inc(PChar(Result), QueryInterfaceThunk.AdjustmentByte);        
      AddLong: Inc(PChar(Result), QueryInterfaceThunk.AdjustmentLong);        
    else    
      Result := nil;      
    end;    
  except      
    Result := nil;    
  end;
end;
Может кто реализовывал подобное?
Буду благодарен за любую помощь.
LISTAT вне форума Ответить с цитированием
Старый 24.01.2013, 09:54   #2
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Цитата:
Да это работает, но хотелось бы просто получив ссылку на интерфейс выйти на класс и вызвать его деструктор.
Да буде вам известно что при уменьшении счетчика ссылок, класс из разряда "в нашем полку убыло" сам уничтожается.
Человек_Борща вне форума Ответить с цитированием
Старый 24.01.2013, 10:30   #3
LISTAT
Пользователь
 
Регистрация: 27.10.2011
Сообщений: 50
По умолчанию

Цитата:
Сообщение от Человек_Борща Посмотреть сообщение
Да буде вам известно что при уменьшении счетчика ссылок, класс из разряда "в нашем полку убыло" сам уничтожается.
А если в классе реализуются методы
_AddRef
_Release
которые не проводят подсчет ссылок или он попросту унаследован от TComponent, то этот метод присвоения указателю интерфейса nil не вызовет деструктор класса.
LISTAT вне форума Ответить с цитированием
Старый 24.01.2013, 10:46   #4
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

А вы объект наследуйте от TInterfacedObject и вашего IMySomeInterface
Человек_Борща вне форума Ответить с цитированием
Старый 24.01.2013, 10:48   #5
LISTAT
Пользователь
 
Регистрация: 27.10.2011
Сообщений: 50
По умолчанию

Цитата:
Сообщение от Человек_Борща Посмотреть сообщение
А вы объект наследуйте от TInterfacedObject и вашего IMySomeInterface
Объект наследуется от TObject, предопределяются методы подсчета ссылок (долго рассказывать зачем, есть своя необходимость).
LISTAT вне форума Ответить с цитированием
Старый 24.01.2013, 10:55   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Почитайте о правильном использовании интерфейсов и ссылок на них, а также связи интерфейса и класса, в результате которой класс, сам, уничтожается при уничтожении ссылки на интерфейс. Долго рассказывать зачем.
Человек_Борща вне форума Ответить с цитированием
Старый 24.01.2013, 11:42   #7
LISTAT
Пользователь
 
Регистрация: 27.10.2011
Сообщений: 50
По умолчанию

Цитата:
Сообщение от Человек_Борща Посмотреть сообщение
Почитайте о правильном использовании интерфейсов и ссылок на них, а также связи интерфейса и класса, в результате которой класс, сам, уничтожается при уничтожении ссылки на интерфейс. Долго рассказывать зачем.
Читал и не раз. Прекрасно понимаю преимущества данного механизма.
На данный момент передо мной стоит задача в разработке плагинной системы. Суть проста - в dll имеем класс, который может реализовывать любой интерфейс. В приложении получаем ссылку на этот интерфейс, вызываем необходимые методы и после этого имеется необходимость уничтожить класс, который реализует ранее запрошенный интерфейс.
Если наследоваться от TInterfaceObject, то как показывает практика иногда ссылкам на интерфейс необдуманно присваивают nil (бывают разработчики плагинов не знающие, что так делать нельзя, пока интерфейс еще нужен), что вызывает деструктор реализуемого класса и в последующем AV. Вот собственно и поэтому предопределены методы подсчета ссылок.
LISTAT вне форума Ответить с цитированием
Старый 24.01.2013, 11:48   #8
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Вы не правильно его реализовываете. Вот к сведению... как-раз по вашей части.
http://www.gunsmoker.ru/2011/12/delphi.html
Человек_Борща вне форума Ответить с цитированием
Старый 24.01.2013, 11:51   #9
LISTAT
Пользователь
 
Регистрация: 27.10.2011
Сообщений: 50
По умолчанию

Цитата:
Сообщение от Человек_Борща Посмотреть сообщение
Вы не правильно его реализовываете. Вот к сведению... как-раз по вашей части.
http://www.gunsmoker.ru/2011/12/delphi.html
Спасибо. На досуге почитаю.
LISTAT вне форума Ответить с цитированием
Старый 24.01.2013, 12:06   #10
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Цитата:
Если наследоваться от TInterfaceObject, то как показывает практика иногда ссылкам на интерфейс необдуманно присваивают nil (бывают разработчики плагинов не знающие, что так делать нельзя, пока интерфейс еще нужен), что вызывает деструктор реализуемого класса и в последующем AV. Вот собственно и поэтому предопределены методы подсчета ссылок.
Ваша задача не беспокоится об ошибках других(это не ваша задача и не ваши проблемы вообще), а о том чтобы эти ошибки не рушили ядро программы, а информировали разработчика плагина о том что такой-то X выкинул финт при таком-то событии Y.
Человек_Борща вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вложенный класс в шаблон. Указатель на вложенный класс в возвращаемом значении метода шаблона. Что делать? Asya1994 Помощь студентам 3 09.12.2012 01:43
Присваивание ссылки на класс интерфейсной ссылке Aleks26 Общие вопросы Delphi 4 11.04.2012 18:43
Функционал программы должен быть реализован как класс, размещенный в отдельном модуле. Сейвс Помощь студентам 0 29.02.2012 10:12
Указатель на абстрактный класс zhenya.ya Общие вопросы C/C++ 0 11.11.2010 23:51
Указатель на класс Колючка* Общие вопросы Delphi 8 21.01.2010 07:38