了解 excel COM 中引用的含义

Understanding the meaning of reference in excel COM

要参考的代码是:

Dim oXL As Microsoft.Office.Interop.Excel.Application
Dim oWBS As Workbooks
Dim oWB As Workbook
Dim oSheet As Worksheet
    
oXL = CreateObject("Excel.Application")
oWBS = oXL.Workbooks
oWB = oWBS.Add

详细解释总结如下: 上面代码中oXL、oWBS、oWB、oSheet都是存储引用。根据定义,引用必须指向内存位置。我想了解的是它们指向相同还是不同的内存位置?

我的想法:我已经用粗体标出了我的问题 我的猜测是这些代表各种引用的内存位置彼此都不相同。我想象如下的表示。假设 oXL(代表 Excel 应用程序)指向内存中的位置“A”。 Workbooks property returns Workbooks collection 的实例。 oWBS 存储由 oXL.Workbooks 返回的引用并指向一个新位置,比如标记到位置 A 的 B。我提到“标记”是因为 oWBS 是针对 oXL 创建的.引用 oWBS 可以访问 ADD 方法。当执行 ADD 方法时,它会添加一个工作簿或更专业的术语 returns WORKBOOK 对象(这也是一个参考)。 oWB 存储此引用并且根据定义必须指向某个内存位置,比如 C 被标记为 B。

我的问题:A、B、C都是不同的内存位置吗?虽然我可能错了,但我仍然可以想象 A 和 B 是独立的内存位置。但是 B 和 C 呢?表示工作簿集合 (B) 的内存位置和实际保存工作簿的位置(其中有一个 sheet)即 C – 它们应该是真正不同的位置吗?如果不是,那么两个引用 oWBSoWB 是否指向同一个位置——如何解释??

概括上述思路,是否意味着每当我们执行 oXL.Workbooks.ADD 添加新工作簿时,我们都会返回三个引用?

  1. 表示 excel 应用程序的引用
  2. 表示 oXL.Workbooks 集合实例的引用
  3. 表示添加的单个工作簿的引用

现在让我们使用 _Workbook.Worksheets.ADD 将工作sheet 添加到工作簿。 扩展上述推理,我们会再次获得 _Workbook.WorksheetsWorksheets.ADD 的唯一引用(指向新的内存位置)吗??

此外,我想声明这更多的是一种学术好奇心。

By definition, a reference must point to a memory location. What I want to understand is whether they point to the same or different memory locations?

在 COM 世界中,对象引用不指向内存位置,尤其是在用 VB.NET 编写的托管应用程序中。在 .Net 中,您处理一个 RCW 对象,该对象将您的调用路由到 COM 对象。在 MSDN 的 Runtime Callable Wrapper 文章中阅读更多相关信息。它声明如下:

The runtime creates exactly one RCW for each COM object, regardless of the number of references that exist on that object. The runtime maintains a single RCW per process for each object. If you create an RCW in one application domain or apartment, and then pass a reference to another application domain or apartment, a proxy to the first object will be used. Note that this proxy is a new managed object and not the same as the initial RCW; this means the two managed objects are not equal but do represent the same COM object.

在 COM 世界中,当您调用 属性 或方法时,例如 oXL.Workbooks 属性 returns Workbooks class 并增加相应 COM 对象的引用计数器。比如说,如果您在原始文件中调用 属性 两次,您将在 .NET 中获得一个新的对象实例,并且引用计数器将增加两次。在这种情况下,您需要为返回的每个对象调用 Marshal.ReleaseComObject 以减少引用计数器。

最后,您可能会发现 Why doesn’t Excel quit? 文章很有帮助。


Also, in this context is there a way to display the reference count against a COM object?

Marshal.ReleaseComObject 方法 returns 与 COM 对象关联的 RCW 引用计数的新值。