powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Индивидуальное определение одноимённой функции под каждый интерфейс
11 сообщений из 11, страница 1 из 1
Индивидуальное определение одноимённой функции под каждый интерфейс
    #38964012
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени суток.

Несколько классов наследуются от IUnknown:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
#include <objbase.h>

// pure abstract base class
interface IX : IUnknown{  
  virtual void __stdcall Fx() = 0; // pure virtual function
};

// pure abstract base class
interface IY : IUnknown{
  virtual void __stdcall Fy() = 0; // pure virtual function
};

// pure abstract base class
interface IZ : IUnknown{
  virtual void __stdcall Fz() = 0; // pure virtual function
};

extern "C"{
  extern const IID IID_IX;
  extern const IID IID_IY;
  extern const IID IID_IZ;
}



Эти интерфейсы я реализую в классе CA (см. код ниже).

Интерфейс IUnknown определяет три функции: QueryInterface, AddRef и Release. Мне нужно, чтобы реализация функции QueryInterface была общей для всех трёх интерфейсов (это успешно работает), а вот функции AddRef и Release должны быть определены индивидуально для каждого интерфейса (с этим как раз таки проблема).

Т.е. если переменная объявлена как IX, то для неё должны использоваться AddRef и Release именно те, которые я хочу определить для IX. Та же история по отношению и к IY, IZ. Это позволит мне вести подсчёт ссылок на компонент для каждого интерфейса (для удобства в отладке). Но синтаксис, который я записал - неверный (см. TODO в комментариях). Как это сделать правильно?

Текущий вариант кода класса CA такой:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
//#include "../../std_lib_facilities.h"
#include <iostream>
#include "IFace.h"

// COM component
class CA :
  public IX,
  public IY,
  public IZ
{
public:
  CA();
  ~CA();
  virtual void __stdcall Fx(); // IX
  virtual void __stdcall Fy(); // IY
  virtual void __stdcall Fz(); // IZ
  // IUnknown
  virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv);
  virtual ULONG __stdcall IX::AddRef(); // for IX instances
  virtual ULONG __stdcall IX::Release(); // for IX instances

  virtual ULONG __stdcall IY::AddRef(); // for IY instances
  virtual ULONG __stdcall IY::Release(); // for IY instances

  virtual ULONG __stdcall IZ::AddRef(); // for IZ instances
  virtual ULONG __stdcall IZ::Release(); // for IZ instances

private:
  // Each interface has own counter (for convenience of debugging)
  ULONG ix_counter;
  ULONG iy_counter;
  ULONG iz_counter;
};

CA::CA() :
ix_counter(0),
iy_counter(0),
iz_counter(0){
  std::cout << "CA:CA()" << std::endl;
}

CA::~CA(){
  std::cout << "CA:~CA()" << std::endl;
}


// TODO: this is wrong syntax (function signature)
ULONG __stdcall CA::IX::Release(){
  InterlockedDecrement(&ix_counter);
  ULONG count = ix_counter + iy_counter + iz_counter;
  if (0 == count) delete this;
  return count;
}

void __stdcall CA::Fx(){ std::cout << "\tFx()" << std::endl; }

void __stdcall CA::Fy(){ std::cout << "\tFy()" << std::endl; }

void __stdcall CA::Fz(){ std::cout << "\tFz()" << std::endl; }

// This is function is the same for each interface
HRESULT __stdcall CA::QueryInterface(const IID& iid, void** ppv){
  HRESULT h = S_OK;
  if (IID_IX == iid){
    *ppv = static_cast<IX*>(this);
    std::cout << "QueryInterface: IX interface returned." << std::endl;
  }
  else if (IID_IY == iid){
    *ppv = static_cast<IY*>(this);
    std::cout << "QueryInterface: IY interface returned." << std::endl;
  }
  else if (IID_IZ == iid){
    *ppv = static_cast<IZ*>(this);
    std::cout << "QueryInterface: IZ interface returned." << std::endl;
  }
  else{
    std::cout << "QueryInterface: Unexpected interface. NULL returned."
      << std::endl;
    h = E_NOINTERFACE;
    *ppv = NULL;
  }
  return h;
}

// TODO: this is wrong syntax (function signature)
ULONG __stdcall CA::IX::AddRef(){
  return InterlockedIncrement(&ix_counter);
}



Спасибо
...
Рейтинг: 0 / 0
Индивидуальное определение одноимённой функции под каждый интерфейс
    #38964027
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Compositum
Интерфейс IUnknown определяет три функции: QueryInterface, AddRef и Release. Мне нужно, чтобы реализация функции QueryInterface была общей для всех трёх интерфейсов (это успешно работает), а вот функции AddRef и Release должны быть определены индивидуально для каждого интерфейса (с этим как раз таки проблема).


Тут мудрить особо не нужно, используй делегирование. Паттерн Proxy кажись.
Т.е. грубо говоря, определи отдельно реализацию, сделай там весь функционал, и вызывай где нужно её, а где не нужно -- не вызывай.

Но вообще достатоно станно, если у тебя есть отдельный AddRef/Release, то это -- отдельный объект, потому как это -- аналоги выделения и освобождения памяти, аналоги создания и удаления объектов. И если у двух разных объектов один QueryInterface -- это как-то странно.

В любом случае, лучше это делать структурно, а не использовать фичи C++.
...
Рейтинг: 0 / 0
Индивидуальное определение одноимённой функции под каждый интерфейс
    #38964036
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Compositum, Ещё раз:

авторИнтерфейс IUnknown определяет три функции: QueryInterface, AddRef и Release. Мне нужно, чтобы реализация функции QueryInterface была общей для всех трёх интерфейсов (это успешно работает), а вот функции AddRef и Release должны быть определены индивидуально для каждого интерфейса (с этим как раз таки проблема).

И код:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
class CA :
  public IX,
  public IY,
  public IZ
{
// ...
};



Это очень странно, поскольку ты хочешь (видимо) создавать и удалять части одного объекта независимо . Как у тебя при этом сам объект будет функционировать, если у него нет одной части ? Не очень понятно. Впрочем, это только замечания, решать тебе.
...
Рейтинг: 0 / 0
Индивидуальное определение одноимённой функции под каждый интерфейс
    #38964037
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,

Я не понял ответа. Специалисты по COM советуют вести отдельный счётчик ссылок для каждого интерфейса, дабы проще было искать ошибки в коде. Декрементирование/инкрементирование ссылок в COM осуществляется посредством AddRef/Release. В книжке пример ведения общего счётчика. Я пытаюсь понять, как реализовать работу со счётчиком отдельно под каждый интерфейс. Буду признателен за пример кода.
...
Рейтинг: 0 / 0
Индивидуальное определение одноимённой функции под каждый интерфейс
    #38964045
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЭто очень странно, поскольку ты хочешь (видимо) создавать и удалять части одного объекта независимо . Как у тебя при этом сам объект будет функционировать, если у него нет одной части ? Не очень понятно. Впрочем, это только замечания, решать тебе.
Я не собираюсь удалять части одного и того же объекта. Доступ к компоненту в COM может быть представлен одновременно произвольным количеством ссылок через различные интерфейсы. Необходимо отслеживать количество "живых" ссылок, дабы понимать, когда компонент должен быть удалён (компонент сам себя удаляет в этом случае). Это несложно сделать для общего счётчика, но рекомендуется делать отдельный счётчик для каждого интерфейса. Вот это я и пытаюсь реализовать.
...
Рейтинг: 0 / 0
Индивидуальное определение одноимённой функции под каждый интерфейс
    #38964054
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Compositum,

Ну я всё, что мог, сказал.
...
Рейтинг: 0 / 0
Индивидуальное определение одноимённой функции под каждый интерфейс
    #38964147
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CompositumКак это сделать правильно?
Правильно - никак. Как обычно -
http://stackoverflow.com/questions/2004820/inherit-interfaces-which-share-a-method-name
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Индивидуальное определение одноимённой функции под каждый интерфейс
    #38964740
Владимир2012
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Оформление класса в виде COM объекта http://club.shelek.ru/viewart.php?id=48
...
Рейтинг: 0 / 0
Индивидуальное определение одноимённой функции под каждый интерфейс
    #38964944
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимир2012Оформление класса в виде COM объекта http://club.shelek.ru/viewart.php?id=48
Спасибо, конечно за ссылку, но я не спрашивал о том, как классы оформлять в виде COM. :) По ссылке: материал, на мой взгляд, изложен сумбурно и не понятно. Я изучаю COM по книге Дейла Роджерсона "Основы COM". В ней материал изложен последовательно и неплохо "разжёван".
...
Рейтинг: 0 / 0
Индивидуальное определение одноимённой функции под каждый интерфейс
    #38964945
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем спасибо, устраивающий меня ответ получен здесь .
...
Рейтинг: 0 / 0
Индивидуальное определение одноимённой функции под каждый интерфейс
    #38965049
Владимир2012
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CompositumЯ изучаю COM по книге Дейла Роджерсона "Основы COM".
Ну да и я начинал с нее ..., а пришел к ATL и ActiveX.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Индивидуальное определение одноимённой функции под каждый интерфейс
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]