【问题标题】:Where are COM method calls executedCOM 方法调用在哪里执行
【发布时间】:2015-04-08 22:11:09
【问题描述】:

假设我正在执行一个用 c# 编写的 exe(只是我选择的语言)。它有以下代码:

var comObj=new ComClass();
comObj.DoSomething();

现在,我想知道DoSomething 方法是在哪个进程中执行的。是当前 exe 正在运行的同一个进程,还是另一个进程响应 DoSomething 调用?

【问题讨论】:

  • 取决于ComClass 所代表的COM 对象的性质,以及它的注册方式。它可能是加载到客户端进程中的 DLL,也可能是同一台机器上的单独进程,甚至是运行在不同机器上的单独进程。
  • downvoter,请注意评论。
  • @VictorMukherjee 可能有人觉得你的问题对 SO 来说并不完全没问题......最后这是一个“理论”问题,许多人可能不喜欢它。来自帮助:Stack Overflow 适用于专业和*的程序员,因为热爱而编写代码的人。我们觉得最好的 Stack Overflow 问题中都有一些源代码,

标签: c# com


【解决方案1】:

这在 COM 中是完全透明的,你也无法从你的程序中发现。它由存储在注册表中的配置信息确定。 COM 服务器需要注册的核心原因。不同的场景是:

  • 在创建对象的同一线程上。当服务器注册为进程内服务器并且线程单元与 COM 对象的线程模型兼容时使用。最常见的情况,尤其是当您在程序的 UI 线程上创建对象时。

  • 在另一个线程上,如有必要,由 COM 创建,为对象提供线程安全的主页。当您的 new 语句在 MTA(多线程单元)中的线程上运行时,通常会发生这种情况。通常来自工作线程。你创建的对象是一个proxy,它的主要工作是序列化你传递给一个方法的参数,并在另一个线程上运行的stub中反序列化它们。它确保对对象的所有调用都是线程安全的。否则,与 .NET Remoting 中使用的机制相同。负责封送处理的底层是 LRPC,这是一个不起眼的 Windows 组件,经过优化可以尽可能快地进行线程间和进程间调用。

  • 在进程内组件的代理进程内。不是很常见,但代理可以非常方便地解决例如进程位数问题。允许您在 64 位进程中使用 32 位服务器。需要 32 位和 64 位代理/存根。

  • 在注册为进程外服务器的另一个进程中。典型的例子是 Microsoft Office 程序,如 Word 和 Excel,在 .NET 编程中非常常见。这就是 COM 开始变得脆弱的地方,当服务器继续运行时,意外的程序中止往往会导致混乱。 SO 的一个非常常见问题。

  • 在另一台机器上的另一个进程中。称为 DCOM 或分布式 COM。需要一个额外的配置步骤来确保可以选择目标机器和正确的帐户权限。以让人类头痛欲裂而臭名昭著,如今已不再使用它。 DCOM 最大的声名是让 Java 在 90 年代后期的中间件战争中吃掉了微软的午餐。

如果您不知道哪些场景适用于您的案例,那么像 SysInternals 的 Process Monitor 这样的实用程序往往会提供洞察力。您将看到您的程序读取注册表,告诉您在哪里查找,并加载 DLL 或启动 EXE。

【讨论】:

    【解决方案2】:

    来自COM Clients and Servers

    有两种主要类型的服务器,进程内和进程外。进程内服务器在动态链接库 (DLL) 中实现,进程外服务器在可执行文件 (EXE) 中实现。进程外服务器可以驻留在本地计算机或远程计算机上。

    我确实认为名称非常明确:-)

    请注意,即使对于进程外 COM 服务器,也会有一些进程内代码在 COM 客户端和 COM 服务器之间进行编组

    【讨论】:

    • 好的,那么,这是否意味着 dll 实现将始终在同一个进程中加载​​,即,如果 ComClass 包含在 dll 中?另外,如果程序集是 exe,它总是在进程外还是可以在进程内加载?
    • @VictorMukherjee 来自同一页:此外,COM 提供了一种机制,允许进程内服务器(DLL)在代理 EXE 进程中运行,以获得能够在远程计算机上运行该进程。有关详细信息,请参阅 DLL Surrogates。 对于 exe,我认为它们始终处于进程外
    最近更新 更多