Search code examples
c#.netcomdirectshow

Instantiating managed COM object in C#


I have written several pure .NET DirectShow filters (they are transform filters) and registered them via regasm. GraphStudioNext has no problems using them.

My problem is when my C# app tries to use the filters -- I have to get .NET to instantiate the COM object as a COM object and not a managed dotnet object. This is because I've implemented a filter selection utility (like GraphStudioNext's insert filter from a list feature) and I can't add a reference to the assembly at compile time -- someone could write a custom .NET DirectShow filter with their own ComImport'ed IBaseFilter. This will cause problems when my code tries to cast the type to IBaseFilter even though their IBaseFilter and my IBaseFilter share the same Guid. As a COM object, this would be no problem. As a .NET object, they're actually different types.

Say one inteded to write GraphStudioNext in C# and have it work with pure .NET DirectShow filters -- is this even possible?


Solution

  • A good question. I dealt with a somewhat similar problem here. Indeed, [ComImport] interface type equivalency doesn't work when you deal with a native .NET object directly. You need to hide the .NET object behind an artificial COM proxy for the COM interface equivalency to work.

    In the solution to my question, I initially used ICustomQueryInterface and Marshal.CreateAggregatedObject to aggregate the .NET object, to expose it as COM object for that reason.

    Later, I ended up implementing my own IUnknown runtime stub (using Marshal.GetFunctionPointerForDelegate for AddRef, Release and QueryInterface), which I used as pOuter (the controlling IUnknown) object for CreateAggregatedObject, so it didn't violate COM identity rules. That was hack-ish, but it solved the problem for me.