描述:
创建了一个进程外com,现在需要几个app共用这个com,现在希望达到如下效果,比如一个app里面createinstance过了,只要这个app不被关掉,那么之后启动的app都将使用原来的实例.看到论坛上有人说过可以用DECLARE_CLASSFACTORY_SINGLETON,单实例进程外组件?我是用ATL创建的com,请问ATL下如何实现单实例进程外组件呢??谢谢
另外进程内com可以通过ICONNECTIONPOINT处理event,那么进程外com也可以通过ICONNECTIONPOINT处理event吗?就是达到com发送一个event,几个app可以同时收到这个event的效果呢?(谢谢,我是com新手,所以问题好多)
解决方案1:
“以下是我com头文件里的部分定义:
class ATL_NO_VTABLE CSimple02 :
public CComObjectRootEx <CComSingleThreadModel>,
public CComCoClass <CSimple02, &CLSID_Simple02>,
public IConnectionPointContainerImpl <CSimple02>,
public CProxy_ISimple02Events <CSimple02>,
public IDispatchImpl <ISimple02, &IID_ISimple02, &LIBID_STEP02Lib>
{
DECLARE_CLASSFACTORY_SINGLETON(CSimple02)
}
然后app里面是
ISimple02 * pISimple02test1;
hr = CoCreateInstance(CLSID_Simple02, NULL, CLSCTX_ALL,
IID_ISimple02, (void **)&pISimple02test1);
ISimple02 * pISimple02test2;
hr = CoCreateInstance(CLSID_Simple02, NULL, CLSCTX_ALL,
IID_ISimple02, (void **)&pISimple02test2);
pISimple02test1和pISimple02test2的内存地址为什么不一样啊??头好大啊 ”
指针当然不一样了,这两个指针是不同的指针。你又没让他们一样。(比如赋值)。
但是他们所指的内容应该是一样的。
连接点的内容你可以看看 ATL技术内幕,vc会自动生成相应的代码的
解决方案3: 现在我该把IClassFactory* pcf = NULL; 改成CMyClassFactory* pcf = NULL; 吗? 不用,不然com就没有意义了,com传递的是接口
CreateInstance,那我要是继续使用CoCreateInstance是不是还是不能彻底解决我之前的问题? 不会
推荐用CComPtr<>::CoCreateInstance 这样不用考虑类厂,用起来也方便
mark 顶
解决方案5: 另外,在微软的知识库也有方法:
Description of an alternative implementation of ATL singleton in Visual C++ 6.0
http://support.microsoft.com/kb/201321
本帖最后由 laiyiling 于 2008-04-22 12:22:05 编辑
2、直接使用CComClassFactorySingleton
也可以达到相同的效果。
用法非常简单,是直接
加一个宏DECLARE_CLASSFACTORY_SINGLETON就可以了
当然,实际上,它的原理和你的思路是一样的
class CMyClass : ..., public CComCoClass< ... >
{
public:
DECLARE_CLASSFACTORY_SINGLETON(CMyClass)
...
};
据我所知,DECLARE_CLASSFACTORY_SINGLETON应该只能做到进程内全局对象,你需要进程外,应该用方案1,控制类厂 解决方案7:
我的方案:
1。 实例,必须控制IClassFactory接口。
在你的对象类声明里
加入
DECLARE_CLASSFACTORY_EX(CMyClassFactory)
CMyClassFactory是你从CComClassFactory继承来的。
重载CreateInstance函数。
CreateInstance函数如下
HRESULT CMyClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
REFIID riid, void** ppvObj)
{
_ASSERTE(m_pfnCreateInstance != NULL); HRESULT hRes = E_POINTER;
static void * pObj = NULL; // 用于保存实例指针
// 如果实例已存在直接返回
if(pObj)
{
*ppvObj = pObj;
((LPUNKNOWN)pObj)->AddRef();
hRes = S_OK;
}
else // 不存在创建新的
{
hRes = m_pfnCreateInstance(pUnkOuter, riid, &pObj);
*ppvObj = pObj;
}
return hRes;
}
你说的没错啊,在ATL中使用DECLARE_CLASSFACTORY_SINGLETON宏就能实现单实例组件。
第二个问题同1楼
友情UP~
解决方案10: 1、进程外COM,自己实现类厂。对进程外组件,类厂被COM保存。这样不同的客户端CoCreateInstance不用分别重建类厂,只需申请类厂指针即可。这样就可以保存组件实例在类厂中,从而实现单件。
2、COM都可以用IConnectionPoint来实现事件机制,不管是载体形式。若几个APP都实现了连接点,当然是都得到通知(非单实例)。谁用AtlAdvise注册了就通知谁