0

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?

Zach Saw
  • 4,308
  • 3
  • 33
  • 49
  • 1
    If you have a problem with your code then you need to show it. – Hans Passant Jun 02 '14 at 16:05
  • 1
    @HansPassant There's no problem with any code. The question if you read it at all is to do with getting .NET to instantiate managed .NET objects as COM object - which I did not know how. So how do you show code that the question was meant to ask in the first place? – Zach Saw Nov 10 '14 at 22:21

2 Answers2

3

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.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
noseratio
  • 59,932
  • 34
  • 208
  • 486
  • 1
    Wow Thank you! Someone who actually read my question and posted a working solution! – Zach Saw Jun 03 '14 at 05:33
  • I've implemented the proxy but in my case it's a little more complicated -- the DS filters have other COM interface like IPin that it returns when queried. Looks like it's not possible to write a GraphStudio-like app in .NET! – Zach Saw Jun 03 '14 at 10:52
  • @ZachSaw, you should be able to implement any interface this way, or even aggregate another COM object, and expose it via [`ICustomQueryInterface`](http://blogs.msdn.com/b/jmstall/archive/2009/07/09/icustomqueryinterface-and-clr-v4.aspx). If you show your code, I might be able to spot the problem. – noseratio Jun 03 '14 at 11:05
  • 1
    Ah the problem isn't in my code. It's in DirectShow.NET. I've passed the COM object to it but the DS filter could be written by someone else using .NET for use with C++ (hence doesn't have the COM proxy). When DirectShow.NET asks for the in / out pins, IPin of .NET type is returned instead of COM object type. I have no control over that part, unless I change DirectShow.NET to create a proxy every time a non COM object is detected. – Zach Saw Jun 03 '14 at 11:08
  • @ZachSaw, I guess I see what you mean, but I don't have any DirectShow.NET experience. – noseratio Jun 03 '14 at 11:47
2

If the filter is registered in the system and you know the CLSID of it, then you can use:

Type filterType = Type.GetTypeFromCLSID(filterClsid);
var filter = (IBaseFilter)Activator.CreateInstance(filterType);

If the filter is not registered in the system, but you know the dll-location and the CLSID, you can do it like in C++. You need some P/Invokes for it! Call LoadLibraryEx and then get the IClassFactory. With this you can IClassFactory::CreateInstance of your filter.

I know this works, because we have done it and we are only using this method to work with custom directshow filters.

CPlusSharp
  • 881
  • 5
  • 15