如何防止在 ATL 类型库中公开 coclass 实现
Posted
技术标签:
【中文标题】如何防止在 ATL 类型库中公开 coclass 实现【英文标题】:How to prevent coclass implementations from being exposed in an ATL type library 【发布时间】:2010-11-14 12:42:49 【问题描述】:我正在构建一个具有类工厂类型的 ATL 类型库。有点像这样:
[ object, uuid(...), ... ]
interface INumber : IDispatch
[propget, id(0)] HRESULT Value([out, retval] LONG* pVal);
[ object, uuid(...), ... ]
interface INumberFactory : IDispatch
[id(1)] HRESULT GetNumber([in] BSTR numberName, [out, retval] INumber* pVal);
[ uuid(...) ]
coclass NumberFactory
[default] interface INumberFactory;
然后用户可以通过NumberFactory
获得实现INumber
接口的类的实例。
这很好用,但我不知道如何定义和实例化通过NumberFactory.GetNumber()
方法返回的 ATL 对象。如果我这样定义 IDL 中的数字:
[ uuid(...) ]
coclass One
[default] interface INumber;
One
coclass 可以由用户实例化。但我想限制它,所以获得One
coclass 实例的唯一方法是调用NumberFactory.GetNumber("One")
。
所以我的问题是:应该如何编写 IDL,以便用户不能实例化 One
,但仍然能够从 NumberFactory
coclass 内部实例化 One
并返回 One
的 INumber
接口给用户?
此外,为了使其正常工作,在 ATL 方面是否必须做一些特别的事情?
【问题讨论】:
【参考方案1】:-
从 IDL 中删除 CoClass
从对象表中删除 CoClass(删除其 OBJECT_ENTRY_AUTO)
保留 CNumber 类
您的 GetNumber(...) 代码应类似于:
*pVal = new CComObject<CNumber>(); (*pVal)->AddRef();
这样用户就不需要创建 CoClass,而您的工厂是唯一可以生产它们的工厂。
【讨论】:
太棒了!这正是我所需要的!谢谢!这实际上比我发现的更好,哈哈... 您还需要从 CComCoClass显然我在寻找错误的东西......我在相关问题中找到了答案(来自侧边栏),即使在提问之前我在搜索时无法找到它......
答案有两个:
-
将
noncreatable
添加到 IDL 中的 coclass 定义中
从 ATL 头文件中删除 OBJECT_ENTRY_AUTO
条目(如果由向导生成,则在底部)
请参阅此 MSDN 文章:http://msdn.microsoft.com/en-us/library/4tc639ss.aspx
【讨论】:
实际上,noncreatable
属性是声明 PublicNotCreatable 类的更好方法,因为您可以定义源接口并允许 [VB6] 客户端对 coclass 进行 Dim WithEvents。否则客户端必须直接使用接口。以上是关于如何防止在 ATL 类型库中公开 coclass 实现的主要内容,如果未能解决你的问题,请参考以下文章
为啥接口上的“添加 IDL 方法”将方法添加到模块以及 CoClass?
ATL ActiveX 控件如何向 javascript 公开布尔值