自己写一个可扩展框架,有点绕,我希望我能说清楚我开发了一个 ATL exe程序 A.EXE 提供 interfaceA 接口和 interfaceAEVENT 连接点
同时我 写了一个 ATL dll 程序 b.dll 对最终用户提供 interfaceB 接口和 interfaceBEvent 事件连接点
现在我的 b.dll 中要调用 A.EVE 的接口以及接收事件。所以我在b.dll工程中引入了 A.EXE 的 idl编译出来的两个文件。通过 CoCreateInstance 可以创建 A.EXE 的对象,并调用接口方法,但是 我如何在B.DLL 中接收a.exe公开的 连接点事件呢?1。 我想仿照 MFC 实现连接点的机制, 新建一个类 然后继承某个基类,在MFC 中需要继承 CCmdTargate, 但是我不知道在ATL 中继承哪个类,或者类模板。2。 在B.DLL 工程中写一个IDL 在IDL 中实现 interfaceAEVENT 的所有方法,然后使用atladvise 挂接,这样的话是不是就将这个接口完全暴露了呢 ? 也就是说 如果我在 OLEVIEW 中看的话,即能看到B.DLL 暴露的interfaceB interfaceBEvent ,又能看到我为了接收A.EXE 而暴露的interfaceAEVENT 这样是不是会引起混乱呢?我想请教大家的是,这两种方法是否都能实现我的要求,哪个更好呢,有没有更顺畅,更好的实现方法呢?
同时我 写了一个 ATL dll 程序 b.dll 对最终用户提供 interfaceB 接口和 interfaceBEvent 事件连接点
现在我的 b.dll 中要调用 A.EVE 的接口以及接收事件。所以我在b.dll工程中引入了 A.EXE 的 idl编译出来的两个文件。通过 CoCreateInstance 可以创建 A.EXE 的对象,并调用接口方法,但是 我如何在B.DLL 中接收a.exe公开的 连接点事件呢?1。 我想仿照 MFC 实现连接点的机制, 新建一个类 然后继承某个基类,在MFC 中需要继承 CCmdTargate, 但是我不知道在ATL 中继承哪个类,或者类模板。2。 在B.DLL 工程中写一个IDL 在IDL 中实现 interfaceAEVENT 的所有方法,然后使用atladvise 挂接,这样的话是不是就将这个接口完全暴露了呢 ? 也就是说 如果我在 OLEVIEW 中看的话,即能看到B.DLL 暴露的interfaceB interfaceBEvent ,又能看到我为了接收A.EXE 而暴露的interfaceAEVENT 这样是不是会引起混乱呢?我想请教大家的是,这两种方法是否都能实现我的要求,哪个更好呢,有没有更顺畅,更好的实现方法呢?
1。 新建一个普通类,
2。 包含 atl 服务器程序 MIDL 编译生成的 _i.c _i.h 文件
3。 继承 IDispatchImpl,CComObjectRootEx,IDispEventImpl 三个模板类,填写对应的模板参数
4。 增加BEGIN_COM_MAP,和BEGIN_SINK_MAP 的描述
5。 在创建此对象的时候使用 new CComObject<此类>的方式创建。这样就可以接收事件了。不过目前还有一些小的问题,客户端推出的时候 服务器报错,估计是计数的问题。
楼主已经用ATL写了
服务器报错,可以用vs调试下,就能找到
也许某个接口指针未release
一种方式是 写一个类,从CComCoClass,IDispatchImpl,IDispEventImpl继承,这样各个父类就实现了iunkown, idispatch,等虚拟的函数功能,我们可以重点关注我们的事件接收代码,由于实现了CComCoClass,所以这时我们新建接收器的时候 就需要用createInstance 来新建对象,而不是用new,这个接收器的生命期是归客户端的 com所管理的。另外一种方式是,直接从IDispEventSimpleImpl,继承,因为IDispEventSimpleImpl 使用内嵌类的方式实现了 idispatch接口,所以我们也无需关注,这时我们的接收器对象可以直接new 出来,不用createinstance。我是用第二种方法实现的,出现了很大周折,是因为我在这个事件接收器的类上使用了ATL_NO_VTABLE 修饰符,而IDispEventSimpleImpl 也使用了ATL_NO_VTABLE ,导致 vtable没有建立起来。这一点还是要多加注意一下, 总想着优化,结果把基本功能都优化掉了。
还有一种方式是可以通过IDispEventImpl,不过这时由于没有指定 类型库和 源事件接口ID ,比较灵活,也比较麻烦,可以在动态的调用COM 的时候使用。