问题描述:现有一接收数据包服务,定制了三个类 CAppMain、CIOCP、CDatabase,其中CIOCP和CDatabase聚合形成CAppMain,现在CAppMain有一个Init()方法,可以初始话CIOCP实例和CDatabase实例,CIOCP是完成端口的封装,包含的方法有RecvData(),CDatabase用于创建OLEDB对象,用于操作数据库,其中提供了一个方法CreateSQL()和WriteToDB(),现在的问题是,RecvData方法中包含验证数据包合法性的程序和解包的程序,而CreateSQL中含有创建存储过程的语句,WriteToDB中包含调用特定的存储过程的语句,现在要求,以COM方式对这个服务进行泛化,并且提供三个方法,要求,不管在什么方法下,只要传入三个函数指针,就可以进行特定的解包、创建存储过程、和写库,大家考虑考虑如何做?

解决方案 »

  1.   

    没明白你的意思,你自己不是已经说了如何做了吗?
    使用三个COM组件,分别实现接口IAppMain、IIOCP、IDatabase(分别对应着CAppMain、CIOCP、CDatabase),要实现不同的数据协议和存储过程的联合,实现特定的支持IAppMain接口的COM组件即可。
    不过我以为你的这个设计不好,应为IAppMain的功能只是生成另外两个COM组件的实例,所以IAppMain的Init应该改为HRESULT Init( [in] CLSIDREF clsidIOCP, [in] CLSIDREF clsidDatabase );在Init的实现中通过调用CreateInstance直接动态创建另外两个COM组件的实例,因此是包容,不是聚合,但是仍可以用聚合的外貌对人(即给人以是聚合的假象),不过有违COM的祖讯(对QueryInterface的调用失败一次,则永远失败)。
      

  2.   

    呵呵,不好意思,我的意思是如何传入函数指针。因为我觉得用连接点来实现太麻烦了,因为很多人根本不会用,用事件也麻烦,所以我就再想,如何传入一个函数指针,具体就是IDL该怎么写,实现类该怎么写。帖子没有表达清楚我的意思,希望各位原谅。
      

  3.   

    为什么要传递函数指针?
    如果你想动态改变对端口的封装或对数据库的操作,就象上面说的一样,将IAppMain中的Init定义为HRESULT Init( [in] CLSIDREF clsidIOCP, [in] CLSIDREF clsidDatabase );即可,在实现IAppMain接口的COM组件中定义两个成员变量,分别记录IIOCP*和IDatabase*,在Init中,先释放原来的IIOCP*和IDatabase*,再根据传入的clsidIOCP和clsidDatabase生成COM组件的实例.
      

  4.   

    因为是给开发员用的。所以要让他们传自己的函数指针进去啊。因为不是我来实现这几个函数的功能啊。还有,开发人员连COM是什么都不是很清楚,更别说你那样用了。他们能正确调用COM组件都不错了。
      

  5.   

    呵呵,函数指针不是数据,是当前进程空间中的一个地址,在跨边界调用(即跨越进程、套间等的调用)情况下是没有办法聚合的。不过如果你可以保证不会发生跨边界调用情况,则可以传递函数指针(虽然不符合规范)。不过由于不能聚合,即不能生成占位代理程序,因此不能指望通过MIDL帮你生成占位代理程序。也就是说自己直接编写本应由MIDL生成的.h文件即可,而在项目中不需要.idl文件的存在。