views:

39

answers:

1

I have an ATL/COM-based DLL, made using VC++ 6.0. It's used for various executables built using VB6.

I want to add some COM interfaces that will not be accessible via VB6, for the internal use of the DLL only. I want them to be COM interfaces rather than just C++ interfaces due to the fact that I'll be using them on objects which I only have COM interface references to (at the time of use).

That is, I don't know (at the time of use) that this pointer points to a CFoo; I just know that it points to an IFoo, where IFoo is a COM interface, published so that VB6 knows about it. From this IFoo pointer, I want to get an IFooInternal pointer, which every class that implements IFoo (not just CFoo) will implement. Moreover, I don't want IFooInternal to be accessible outside of the DLL itself; for example, I don't want IFooInternal to be accessible by VB6.

Any help with this would be greatly appreciated. Suggestions for alternate ways to accomplish the same overall goal would also be. Thanks in advance.

A: 

Answering my own question for the benefit of anyone who finds this thread in the future. However, please note that I am just guessing here, based on experimentation... it seems to work, at least in my specific situation, but I don't know.

First, in some appropriate header file (perhaps Hidden.h), put the following, replacing a newly generated UUID with a newly generated 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__

For how to define other types of parameters and such for a function, refer to the C++ header that was generated by MIDL from your IDL file.

Next, in the header for any class that you want to implement this interface, add the interface to the class declaration:

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

Also add it to the 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

And from there on out it's just a matter of adding the standard C++ declarations and definitions of the interface's functions to the class:

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

(...)

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

   *pVal = 37;

   return S_OK;
}

I hope this helps someone in the future. I also hope that it doesn't hurt me due to it being incorrect. As I said, though, it seems to work.