描述:
用ATL写一个Free的MTA组件,然后在VB里面调用,按我的理解组件应该进入MTA,VB的对组件的调用和组件对VB的回调通过隐藏的消息窗口,不知是不是这样的,请高手指点。
解决方案1:
对于1:线程是通过执行窗口关联的消息处理函数来处理窗口的消息,因此那个隐藏窗口的消息处理函数中应该是操作另一个COM提供的标准对象——占位管理器(其包含了每个接口的占位组件),然后通过占位来将传过来的参数等信息散集并调用真正的组件对象。至于是否每个STA套间都有一个隐藏窗口,这就不清楚了,因为窗口的用处就只是将信息传给占位管理器,要多个没有什么意义,估计应该是每线程只有一个隐藏窗口。
对于2:的确是那样,如果在非主STA套间中创建了一个Single组件,将是跨套间访问,获得的指针是代理对象。因为必须要保证全局和静态变量的线程安全。
对于3:不知道楼主是否为使用的接口都生成了代理/占位组件,不过如果接口是IDispatch派生的双接口则不用。
对于第一个问题,我对VB不熟,不知道其调试和最终有什么区别,但如果代理/占位没问题可能是组件的代码有什么问题,如那个Fire的线程的接口指针获得是否是通过CoMarshalInterface等类似函数获得的、Fire的线程也需要调用CoInitialize/Ex来初始化。
对于第二个问题,由于不知道VB调试和最终的区别,不清楚原因。但是即使使用模式对话框来挂起界面线程,COM还通过消息过滤器(一个实现了IMessageFilter接口的对象)来防止类似这种的死锁,因为模式对话框依然是通过一个消息循环(有别于此界面线程的主消息循环)来实现模式效果的。而为什么VB调试和运行时不一样,只好抱歉了。