1

我有一个使用 VC++ 6.0 制作的基于 ATL/COM 的 DLL。它用于使用 VB6 构建的各种可执行文件。

我想添加一些无法通过 VB6 访问的 COM 接口,仅供 DLL 内部使用。我希望它们是 COM 接口而不仅仅是 C++ 接口,因为我将在我只有 COM 接口引用的对象上使用它们(在使用时)。

也就是说,我不知道(在使用时)这个指针指向一个 CFoo;我只知道它指向一个 IFoo,其中 IFoo 是一个 COM 接口,发布以便 VB6 知道它。从这个 IFoo 指针,我想得到一个 IFooInternal 指针,每个实现 IFoo 的类(不仅仅是 CFoo)都将实现它。此外,我不希望 IFooInternal 可以在 DLL 本身之外访问;例如,我不希望 VB6 可以访问 IFooInternal。

对此的任何帮助将不胜感激。对于实现相同总体目标的替代方法的建议也是如此。提前致谢。

4

2 回答 2

2

为了将来发现此线程的任何人的利益,回答我自己的问题。但是,请注意,我只是在这里猜测,基于实验......它似乎有效,至少在我的具体情况下,但我不知道。

首先,在一些适当的头文件(可能是 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__

有关如何为函数定义其他类型的参数等,请参阅 MIDL 从您的 IDL 文件生成的 C++ 头文件。

接下来,在要实现此接口的任何类的标头中,将该接口添加到类声明中:

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;
}

我希望这对将来的某人有所帮助。我也希望它不会因为它不正确而伤害我。不过,正如我所说,它似乎有效。

于 2009-10-01T21:04:11.330 回答
0

这听起来不像是一个必然需要 COM 的问题。记住:如果你IFoo*从 COM 中得到一个 unmarshalled,它只是一个普通的IFoo*——而不是什么神奇的 COM-Thing。所以你可以做的就是简单地定义一个普通的 C++ 接口IFooInternal,然后 dynamic_cast 你IFoo*的。

于 2022-01-18T08:41:19.570 回答