У меня есть COM-объект, CProvider, реализованный с использованием ATL. Этот класс включает другой класс, CProviderInfo и поддерживает статический вектор объектов этого внутреннего типа класса.Может ли существующий простой класс C++ реализовать интерфейс IDL без перехода в класс COM?
Вот как это выглядит:
//-------------
// CProvider.h
//-------------
//
// COM object class
//
class ATL_NO_VTABLE CProvider :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CProvider, &CLSID_Provider>,
public Interface1,
public Interface2
{
public:
BEGIN_COM_MAP(CProvider)
COM_INTERFACE_ENTRY(Interface1)
COM_INTERFACE_ENTRY(Interface2)
END_COM_MAP()
//
// The inner class
//
class CProviderInfo
{
public:
CProviderInfo();
CComBSTR m_strName;
GUID m_guidRegistration;
};
private:
//
// static vector of inner class type
//
static vector<CProviderInfo> m_vProviderInfo;
};
То, что я хотел бы сделать, это ввести метод на CProvider, который возвращает копию статического вектора m_vProviderInfo. Попытка играть по правилам COM, я представил новый интерфейс IDL IProviderInfoRetriever для этой цели:
//---------
// IDL file
//---------
//
// IProviderInfoRetriever interface
//
[
// uuid, version ... etc.
]
interface IProviderInfoRetriever : IUnknown
{
HRESULT GetProviderInfo(
[out, retval] SAFEARRAY(IProviderInfo*) *ppProviderInfo);
}
//
// The interface of the class holding the info
//
[
// uuid, version ... etc.
]
interface IProviderInfo : IUnknown
{
[propget]
HRESULT Name(
[out, retval] BSTR *pbstrName);
[propget]
HRESULT Registration(
[out, retval] GUID *pguidRegistration);
}
Мой план должен иметь CProvider реализовать IProviderInfoRetriever эффективно копирование содержимого статического вектора m_vProviderInfo в выходной SAFEARRAY от IProviderInfoRetriever :: GetProviderInfo().
Мой вопрос: можно ли иметь внутренний класс CProviderInfo реализации IProviderInfo? Будет ли это нарушать существующий код, который создает локальные переменные типа CProviderInfo?
Что вы подразумеваете под словом «COM-класс», если не «класс, который реализует один или несколько COM-интерфейсов»? И нет, ничто не мешает вам создать, скажем, экземпляр «CProvider» в стеке («CProvider», по-видимому, являющийся «COM-классом» по любому определению, которое вы имеете в виду). –
Еще одна альтернатива, касающаяся вас «CProviderInfo», заключалась бы в том, чтобы написать класс-оболочку, который реализует 'IProviderInfo', и содержит' CProviderInfo' как член (или даже просто указатель на элемент или индекс в оригинал вектор). Это прекрасно изолирует части, связанные с COM, и минимизирует след на остальной части кодовой базы. –
@IgorTandetnik Вот что я и подумал. После некоторых исследований я обнаружил, что наследование IUnknown приведет к поломке существующего кода, потому что он превратит ** CProviderInfo ** в абстрактный класс. Невозможно создать экземпляр ** CProviderInfo **, за исключением CComObject, CComObjectStack и этого семейства классов, поскольку он обеспечивает реализацию элементов IUnknown. –