2009-10-01 6 views
0

У меня есть DLL на основе ATL/COM, созданная с использованием VC++ 6.0. Он используется для различных исполняемых файлов, построенных с использованием VB6.ATL/COM: Определение COM-интерфейса, который не будет доступен за пределами DLL?

Я хочу добавить некоторые COM-интерфейсы, которые не будут доступны через VB6, для внутреннего использования только DLL. Я хочу, чтобы они были COM-интерфейсами, а не только интерфейсами C++ из-за того, что я буду использовать их для объектов, к которым у меня есть только ссылки интерфейса COM (во время использования).

То есть, я не знаю (во время использования), что этот указатель указывает на CFoo; Я просто знаю, что это указывает на IFoo, где IFoo является COM-интерфейсом, опубликованным так, что VB6 знает об этом. Из этого указателя IFoo я хочу получить указатель IFooInternal, который будет реализовывать каждый класс, который реализует IFoo (а не только CFoo). Более того, я не хочу, чтобы IFooInternal был доступен вне самой DLL; например, я не хочу, чтобы IFooInternal был доступен VB6.

Любая помощь с этим была бы весьма признательна. Также будут предложены альтернативные способы достижения одной и той же общей цели. Заранее спасибо.

+0

Duplicate http://stackoverflow.com/questions/1191012/how-to-prevent-coclass-implementations-from-being-exposed-in-an-atl-type-library/1192207#1192207 –

+0

Это * не * дубликат вопроса, с которым вы связались. В этом вопросе интерфейс будет открыт для Visual Basic (и других клиентов за пределами самой DLL). Это именно то, что я пытаюсь * избегать *. – 2009-10-01 21:16:11

ответ

1

Отвечая на мой собственный вопрос в пользу любого, кто найдет эту тему в будущем. Однако, обратите внимание, что я просто угадываю здесь, основываясь на экспериментах ... кажется, работает, по крайней мере, в моей конкретной ситуации, но я не знаю.

Во-первых, в какой-то соответствующий файл заголовка (возможно, Hidden.h), поставить следующее, заменив вновь образовавшеес UUID с вновь сгенерированного UUID:

#ifndef __Hidden_h__ 
#define __Hidden_h__ 

extern "C" { 

#ifndef __IHidden_FWD_DEFINED__ 
#define __IHidden_FWD_DEFINED__ 
typedef interface IHidden IHidden; 
#endif // __IHidden_FWD_DEFINED__ 

#ifndef __IHidden_INTERFACE_DEFINED__ 
#define __IHidden_INTERFACE_DEFINED__ 

EXTERN_C const IID IID_IHidden; 

MIDL_INTERFACE("a newly generated UUID") 
IHidden : public IUnknown 
{ 
    public: 
     virtual HRESULT STDMETHODCALLTYPE get_Something (
      long __RPC_FAR *pVal) = 0; 
}; 

#endif // __IHidden_INTERFACE_DEFINED__ 

} 

#endif // __Hidden_h__ 

О том, как определить другие типы параметров и т. д. для функции, обратитесь к заголовку C++, который был сгенерирован MIDL из вашего файла IDL.

Далее в заголовке для любого класса, который вы хотите реализовать этот интерфейс, добавить интерфейс для объявления класса:

class ATL_NO_VTABLE CBlah : 
    public CComObjectRootEx<CComSingleThreadModel>, 
    public CComCoClass<CBlah, &CLSID_CBlah>, 
    public ISupportErrorInfo, 
    public IConnectionPointContainerImpl<CBlah>, 
    public IBlah, 
    public IHidden 

также добавить его в COM_MAP:

BEGIN_COM_MAP(CBlah) 
    COM_INTERFACE_ENTRY(IBlah) 
    COM_INTERFACE_ENTRY(ISupportErrorInfo) 
    COM_INTERFACE_ENTRY(IConnectionPointContainer) 
    COM_INTERFACE_ENTRY(IHidden) 
END_COM_MAP 

И оттуда это просто вопрос добавления стандартных деклараций C++ и определений функций интерфейса к классу:

public: 
    STDMETHOD(get_Something)(long *pVal); 

(...)

STDMETHODIMP CBlah::get_Something(long *pVal) 
{ 
    if (!pVal) 
    { 
     (error handling) 
    } 

    *pVal = 37; 

    return S_OK; 
} 

Я надеюсь, что это поможет кому-то в будущем. Я также надеюсь, что это не причинит мне вреда из-за неправильности. Однако, как я уже сказал, это работает.