3

I am implementing something in COM where I new up some objects (FilterGraph IFilters in this case) and each time I new up another, I'd like to iterate over the previous list and see if the one I'm about to add is "already on the graph" (already in the list). My first thought was to just use pointer equality (didn't work). Then I thought to compare by CLSID.

Is there a way to get the CLSID from an "arbitrary" COM object?

Closest I could find was: newing up guid's from the display name's substring

Problems accessing the Running Object Table

and what is CLSID of COM object I just ran in Visual Basic (which uses CreateObject however I'm using an EnumMoniker not CreateObject).

(as a note, I've discovered IBaseFilter/IMediaFilter's parent class IPersist has a GetClassID method I can use, but for the sake of curiosity, is there a more generic way...)

Community
  • 1
  • 1
rogerdpack
  • 62,887
  • 36
  • 269
  • 388
  • I'm confused. You say you've just created a brand new object - how can it possibly be that the same object already exists in your list? Did it travel back in time? As to obtaining `CLSID` - yes, you query the interface pointer for `IPersist` and call `GetClassID`. If the object doesn't implement `IPersist`, you are sadly out of luck (not every COM object has a `CLSID` associated with it in the first place). – Igor Tandetnik Jan 05 '16 at 06:16
  • @IgorTandetnik In this case, it seems to be a "new instantiation" of, for instance, a capture filter. So a "capture filter" that represents the same physical capture device, but I've instantiated it twice, I guess that's possible. In essence, I'm trying to detect if two filters "are the same capture device" FWIW. – rogerdpack Jan 05 '16 at 14:23
  • 1
    I'm not at all familiar with DirectX. I would imagine a COM object representing a physical device would provide a way to obtain a name or ID or something identifying this device. Then you would retrieve these IDs from both objects, and compare them. There is no generic "do these two arbitrary COM objects represent the same physical item" check, if only because COM objects don't generally represent physical items. You appear to expect a general solution to a domain-specific problem; I do not think this is a reasonable expectation. – Igor Tandetnik Jan 05 '16 at 15:00

1 Answers1

1

CLSID tells object class ("type") of COM object, esp. the identifier you can use with CoCreateInstance to create another instance of an object of the same class.

Comparing non-null CLSIDs you can tell that objects are of the same class, however it does not necessarily mean that the objects are interchangeable. Sometimes you can enumerate public properties and compare them as well, but it is still not reliable approach for arbitrary objects.

Specifically with DirectShow API, registered filters that are instantiated using CoCreateInstance would typically report unique CLSIDs. However those created using monikers (devices, compressors) would rather have shared CLSID and are per-initialized to use specific resource, and filters with the same identifier are not necessarily "equal".

Roman R.
  • 68,205
  • 6
  • 94
  • 158
  • You're right. Two COM objects might have same CLSID that are as related as "Logitech Webcam 500" (USB Video capture device) and "SMI Capture Grabber" (another unrelated USB Video capture device) so that's obviously not enough. Since I'm creating them via IEnumMoniker, I guess I'm going to "hope" that the IMoniker#GetDisplayName name is "unique enough" to differentiate the same hardware (perhaps IMonker#IsEqual just compares that?)... – rogerdpack Jan 05 '16 at 20:20
  • 1
    If you are going to reuse them, I would suggest to simply keep moniker display name with the COM pointer and compare the strings to decide if you can recycle the unused pointer. Moniker display name is supposed to be unique. – Roman R. Jan 05 '16 at 20:34