ATL/COM:定义一个在 DLL 之外不可用的 COM 接口?

发布于 2024-08-06 14:03:49 字数 434 浏览 10 评论 0原文

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

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

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

任何对此的帮助将不胜感激。还可以提出实现相同总体目标的替代方法的建议。提前致谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

素年丶 2024-08-13 14:03:49

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

首先,在某个适当的头文件(可能是 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;
}

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

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.

月野兔 2024-08-13 14:03:49

这听起来不像是一个必须需要 COM 的问题。请记住:如果您从 COM 获得未编组的 IFoo*,它只是一个普通的 IFoo* – 而不是一些神奇的 COM-Thing。因此,您可以做的就是简单地定义一个普通的 C++ 接口 IFooInternal,然后将您的 IFoo* 动态转换为该接口。

This doesn't sound like a problem that necessarily needs COM. Remember: If you get an unmarshalled IFoo* from COM, it is just a normal IFoo* – not some magic COM-Thing. So what you can do is simply define a normal C++-Interface IFooInternal and then dynamic_cast your IFoo* to that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文