写了一个COM组件,支持事件,在事件的参数列表中返回一个内部的COM对象, 也就是使用CComObject<type>::CreateInstance来创建的, 这个内部的对象支持IDispatch接口, 通过单步调试, 在VB.net中事件是可以被触发的, 但是参数对象总是Nothing,我的Fire_XXX(IDispatch* pDisp)函数是这样定义的, VB.net中事件是以这样的格式定义的:
对象变量名_事件名(ByVal 参数名 as Object) Handles 对象变量名.事件名, 请问有谁做过这方面的程序, 或者知道, 请指教,谢谢了.

解决方案 »

  1.   

    返回类型要用IDispatch** ppDisp,在IDL中要对该参数设置[out]属性。事件方法中尽量避免使用返回接口的参数类型,因为事件可能被多个客户端接收,那么谁来负责返回呢?如果第一个接收者返回了一个指针,第二个接收者也要返回一个指针,那么第一个返回的组件就失去了减少引用计数的机会,组件可能永远不会释放。
      

  2.   

      胡大哥, 你说的是什么意思, 我不明白, 我要做的事情是在组件中监控一个某事件, 当这一事件发生时, 在组件内部使用CComObject<type>::CreateInstance来创建一个对象, 将这个对象作为参数传递给Fire_XXX函数, 客户方的事件中来使用这个对象, 事件的触发在在组件内部产生的, 是由组件来调用客户方的函数, 作为要传递的参数应该是[in]才是, 怎么会是[out]呢? 我按照你说的方法试过, 好像不行, 还是一样, 客户方事件能够被触发但是接收到的参数对象还是Nothing.
      

  3.   

    搞错你的意思了,我以为你是想让客户端返回一个组件给服务器。大致这样做:CComObject<Cxxx>* obj = NULL;
    CComObject<Cxxx>::CreateInstance(&obj);
    obj->AddRef(); // 这句是必须的Fire_SomeEvent((IDispatch*)obj);obj->Release(); // 这句也是必须的
      

  4.   

      问题解决了, 不是方法的问题, 方法是对的, 只是我之前传进来的对象参数的指针是个空的, 改过就好了, 可以使用了, 谢谢楼上的回答, 不过又有新的问题来了, 在VB.net单步调试进入事件后, VB.net给出这样的一个提示: 托管调试助手“DisconnectedContext”在“E:\Project\Component\TestVB\bin\Debug\TestVB.vshost.exe”中检测到故障。其他信息: 上下文 0x1a0ba0 已断开连接。将不会使用代理来处理 COM 组件上的请求。这可能会导致损坏或数据丢失。要避免此问题,请确保在应用程序全部完成 RuntimeCallableWrapper (表示其内部的 COM 组件)之前,所有上下文/单元都保持活动状态。但是如果是非调试运行就没有这样的提示, 我的组件结构是这样的, 一个组件(单纯模型), 在组件中自己创建一个新的线程, 在线程中有窗口过程, 用以监控消息, 当触发消息时, 就在窗口过程的线程中直接来调用Fire_XXX函数, 不知道这样有没有什么问题, 与这个提示有没有什么关系?
      

  5.   

    Fire_XXX不能在其它线程中调用,必须在组件线程中调用。网上有个atlcpimplmt的库,微软的人写的,可用于跨线程Fire事件,只有一个头文件,把你的组件类修改一下,原来是从IConnectionPointImpl派生的,改成从IConnectionPointImplMT派生即可。