【问题标题】:how do you compare two arbitrary COM objects (can you get CLSID for arbitrary object?)你如何比较两个任意 COM 对象(你能得到任意对象的 CLSID 吗?)
【发布时间】:2016-01-05 22:10:52
【问题描述】:

我在 COM 中实现了一些东西,我在其中新建了一些对象(在这种情况下为 FilterGraph IFilters),每次我新建另一个对象时,我想遍历前一个列表,看看我是否要add 是“已经在图表上”(已经在列表中)。我的第一个想法是只使用指针相等(没有用)。然后我想通过CLSID进行比较。

有没有办法从“任意”COM 对象中获取 CLSID?

我能找到的最接近的是:从显示名称的子字符串中更新 guid

Problems accessing the Running Object Table

what is CLSID of COM object I just ran in Visual Basic(它使用 CreateObject,但我使用的是 EnumMoniker 而不是 CreateObject)。

(作为说明,我发现 IBaseFilter/IMediaFilter 的父类 IPersist 有一个可以使用的 GetClassID 方法,但为了好奇,有没有更通用的方法...)

【问题讨论】:

  • 我很困惑。您说您刚刚创建了一个全新的对象 - 同一个对象怎么可能已经存在于您的列表中?它是否及时返回?至于获取CLSID - 是的,您查询IPersist 的接口指针并调用GetClassID。如果对象没有实现IPersist,那么你很不幸(并不是每个 COM 对象都有一个与之关联的CLSID)。
  • @IgorTandetnik 在这种情况下,它似乎是例如捕获过滤器的“新实例化”。所以一个代表相同物理捕获设备的“捕获过滤器”,但我已经实例化了两次,我想这是可能的。从本质上讲,我正在尝试检测两个过滤器是否“是相同的捕获设备”FWIW。
  • 我对 DirectX 一点也不熟悉。我会想象一个表示物理设备的 COM 对象将提供一种获取名称或 ID 或标识该设备的东西的方法。然后,您将从两个对象中检索这些 ID,并进行比较。没有通用的“这两个任意 COM 对象是否代表相同的物理项目”检查,如果仅仅是因为 COM 对象通常不代表物理项目。您似乎期待针对特定领域问题的通用解决方案;我不认为这是一个合理的期望。

标签: com directshow equality


【解决方案1】:

CLSID 告诉 COM 对象的对象类(“类型”),尤其是。您可以与CoCreateInstance 一起使用的标识符来创建同一类对象的另一个实例。

比较非空 CLSID 可以看出对象属于同一类,但这并不一定意味着对象可以互换。有时您也可以枚举公共属性并进行比较,但对于任意对象仍然不是可靠的方法。

特别是使用 DirectShow API,使用CoCreateInstance 实例化的注册过滤器通常会报告唯一的 CLSID。然而,那些使用名字对象(设备、压缩器)创建的对象宁愿共享 CLSID 并经过初始化以使用特定资源,并且具有相同标识符的过滤器不一定“相等”。

【讨论】:

  • 你是对的。两个 COM 对象可能具有与“Logitech Webcam 500”(USB 视频捕获设备)和“SMI Capture Grabber”(另一个不相关的 USB 视频捕获设备)相关的相同 CLSID,因此这显然是不够的。由于我是通过 IEnumMoniker 创建它们的,我想我会“希望” IMoniker#GetDisplayName 名称“足够独特”以区分相同的硬件(也许 IMonker#IsEqual 只是比较它?)...跨度>
  • 如果您要重用它们,我建议您只需将 moniker 显示名称与 COM 指针一起保留,然后比较字符串以确定是否可以回收未使用的指针。名字对象显示名称应该是唯一的。
猜你喜欢
  • 1970-01-01
  • 2021-09-09
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-15
相关资源
最近更新 更多