4

我正在开发一个具有一些 COM 接口的 API。问题在于 API 通过一个接口进行通信,该接口必须由加载该 API 的项目实现。因此,如果我要使用 API,我会将其加载到我的项目中并创建一个类,该类将实现 API 调用的方法,以通知我某些事情或将结果传递给我。

这显然成为了编组的噩梦。此外,由于还有一些中间对象通过 API 将调用从不同的插件和管理器传递到所有实现为通知调用的方法的对象,这些对象已将自己注册到 API 通知程序,这在术语上已经失控的复杂性。

我在想,为了缩短加载 API 的人需要完成的工作,如果 API 遵循自由线程模型,MFC 生成的类(例如对话框)是否可以实现所需的 COM 接口通知?请记住,这样的对象需要在 API 端转为 IStream 并转回接口,以便 API 可以调用这些方法。

据我所知,MFC 对话框默认是 STA。有没有办法可以强制他们改变或开始 MTA?从 COM 的角度来看,这是否合法?我试图避免创建另一个对象来处理另一个线程中的通知,因为它会使事情复杂化。此 API 需要在多个地方使用,有时在 GUI 中,有时在服务中等。

4

1 回答 1

2

我的理解是 API 本身不限于控制线程,您的意图是通过 COM 接收器接口获取后台线程的通知。

三种方法可以同时解决保持 COM 友好的问题。最简单的方法是更改​​应用程序的全局单元模型,以便将“主”GUI 线程初始化为 MTA。虽然这可能有效,但您可能很快就会发现这与其他东西不兼容,例如使用“Arartment”线程模型注册的 ActiveX 控件。

另一种选择是稍微违反 COM 线程准则,以便 API 直接从后台线程使用接收器接口,而不对其进行编组。这将与准备在侧线程上接收调用的 MFC 应用程序一起正常工作,并且实际上很容易做到(只需在 API 端的线程/单元之间自愿传递接收器接口指针)。当 API 被检测到跨单元接口指针使用的 .NET 客户端使用时,问题可能会在稍后出现。

为了使它对 COM 友好并且仍然在 UI 线程上使用 STA 线程,您可以实现以下场景。API 可以是 STA 组件,直接接受传入的 sink 接口(STA 中 MFC 类实现的 COM 对象,或者更简单的东西,例如直接在窗口类上实现的 COM 接口等)。API 编组将接口指针接收到 MTA 中,以便在工作线程上使用 (CoMarshalInterThreadInterfaceInStream和朋友)。API 使用未编组的指针从 MTA 线程传递通知。这通常包括 threda 切换到您不想要的原始线程,因此为了避免这种情况,MFC 端通知类应该实现自由线程封送器。这将改变一些事情,以便未编组的接口指针直接在工作线程上接收调用,而 MFC 应用程序将负责线程同步(关键部分等)。这是 STA、COM 友好、API 工作线程和高效的同时。

于 2013-09-19T08:56:14.177 回答