|
Jan
22
Written by:
Jeremiah Morrill
1/22/2009 8:44 PM
I'm having many issues with how .NET handles COM objects while writing this EVR custom presenter. I'm getting around it by writing my own COM wrapper for the 'trouble making' COM objects (most notibly IMFSample). Here is the base class for the custom COM wrapper I am going to use. It's a bit more boiler plate, but it will be well worth it :). abstract public class Unknown
{
private readonly IntPtr m_comPointer;
private delegate int AddRefDelegate(IntPtr comPointer);
private delegate int ReleaseDelegate(IntPtr comPointer);
private delegate int QueryInterfaceDelegate(IntPtr comPointer, ref Guid riid, IntPtr ppvObject);
private AddRefDelegate AddRefMethod;
private ReleaseDelegate ReleaseMethod;
private QueryInterfaceDelegate QueryInterfaceMethod;
protected Unknown(IntPtr comPointer)
{
m_comPointer = comPointer;
SetupIUnknownMethods();
}
private void SetupIUnknownMethods()
{
/* Read the COM v-table pointer */
IntPtr pVtable = Marshal.ReadIntPtr(m_comPointer);
const int ADDREF_VTABLE_INDEX = 1;
const int RELEASE_VTABLE_INDEX = 2;
const int QUERYINTERFACE_VTABLE_INDEX = 0;
/* Get the function pointer */
IntPtr pFunc = Marshal.ReadIntPtr(pVtable, ADDREF_VTABLE_INDEX * IntPtr.Size);
/* Cast the function pointer to a .NET delegate */
AddRefMethod = (AddRefDelegate)Marshal.GetDelegateForFunctionPointer(pFunc, typeof(AddRefDelegate));
/* Rinse and repeat */
pFunc = Marshal.ReadIntPtr(pVtable, RELEASE_VTABLE_INDEX * IntPtr.Size);
ReleaseMethod = (ReleaseDelegate)Marshal.GetDelegateForFunctionPointer(pFunc, typeof(ReleaseDelegate));
pFunc = Marshal.ReadIntPtr(pVtable, QUERYINTERFACE_VTABLE_INDEX * IntPtr.Size);
QueryInterfaceMethod = (QueryInterfaceDelegate)Marshal.GetDelegateForFunctionPointer(pFunc, typeof(QueryInterfaceDelegate));
}
public int AddRef()
{
return AddRefMethod(m_comPointer);
}
public int Release()
{
return ReleaseMethod(m_comPointer);
}
public int QueryInterface(IntPtr comPointer, ref Guid riid, IntPtr ppvObject)
{
return QueryInterfaceMethod(comPointer, ref riid, ppvObject);
}
public IntPtr ComPointer
{
get { return m_comPointer; }
}
}
Tags:
12 comment(s) so far...
Re: Custom .NET –> COM Interop
Hey Jer, keep up the great work. There is some good code you may be interested in at: babgvant.com/files/folders/evrplay/category1354.aspx
By Jarrett Vance on
1/25/2009 7:51 PM
|
Re: Custom .NET –> COM Interop
Now you've got the idea. V-Table and function pointers is the way to go. A good buddy of mine does his C# filters using this same approach its much cleaner and more efficient than allowing the runtime to Marshal COM objects. You also avoid STA/MTA cross-thread "no interface" limitations.
It works nice to do it in generics too, and then make pseudo directshow interfaces.. eg;
class ComBase { internal IntPtr _ptr;
// Helper method to create a delegate off the pointer internal static T CreateDelegate(IntPtr ptr, Type interfaceType, string MethodName) { int relativeMethodIndex = -1; System.Reflection.MethodInfo[] ar = interfaceType.GetMethods(); for (int i = 0; i (ptr, IMemInputPinType, "GetAllocator"); _NotifyAllocator = CreateDelegate(ptr, IMemInputPinType, "NotifyAllocator"); _GetAllocatorRequirements = CreateDelegate(ptr, IMemInputPinType, "GetAllocatorRequirements"); _Receive = CreateDelegate(ptr, IMemInputPinType, "Receive"); _ReceiveMultiple = CreateDelegate(ptr, IMemInputPinType, "ReceiveMultiple"); _ReceiveCanBlock = CreateDelegate(ptr, IMemInputPinType, "ReceiveCanBlock"); }
#region IMemInputPin Members delegate HRESULT GetAllocatorDelegate(IntPtr ptr, out IMemAllocator ppAllocator); public HRESULT GetAllocator(out IMemAllocator ppAllocator) { return _GetAllocator(_ptr, out ppAllocator); }
delegate HRESULT NotifyAllocatorDelegate(IntPtr ptr, IntPtr pAllocator, bool bReadOnly); public HRESULT NotifyAllocator(IntPtr pAllocator, bool bReadOnly) { return _NotifyAllocator(_ptr, pAllocator, bReadOnly); }
delegate HRESULT GetAllocatorRequirementsDelegate(IntPtr ptr, out AllocatorProperties pProps); public HRESULT GetAllocatorRequirements(out AllocatorProperties pProps) { return _GetAllocatorRequirements(_ptr, out pProps); }
delegate HRESULT ReceiveDelegate(IntPtr ptr, IMediaSample pSample); public HRESULT Receive(IMediaSample pSample) { return _Receive(_ptr, pSample); }
delegate HRESULT ReceiveMultipleDelegate(IntPtr ptr, IMediaSample[] pSamples, int nSamples, out int nSamplesProcessed); public HRESULT ReceiveMultiple(IMediaSample[] pSamples, int nSamples, out int nSamplesProcessed) { return _ReceiveMultiple(_ptr, pSamples, nSamples, out nSamplesProcessed); }
delegate HRESULT ReceiveCanBlockDelegate(IntPtr ptr); public HRESULT ReceiveCanBlock() { return _ReceiveCanBlock(_ptr); }
#endregion }
The C# TS source filter/demux mentioned the other day use the lame .NET automatic Marshalling -- but I hadn't come up against any problems with it, (if it ain't broke dont fix it etc.)
Good luck!
By Sichbo on
2/1/2009 8:04 AM
|
Re: Custom .NET –> COM Interop
heh looks like theres a bug in this comment thing... seems to have cropped the middle portion of that code :) eh well
By Sichbo on
2/1/2009 8:10 AM
|
Re: Custom .NET –> COM Interop
Thats good stuff Sichbo!
I won't claim that the DNN has the best blog system...
If you'd like to email me (I'd love to hear more!), my email is jeremiah.morrill [at] gmail dot com
-Jer
By Jeremiah Morrill on
2/1/2009 10:43 AM
|
Re: Custom .NET –> COM Interop
I love this article , Very good collection of information
By Burberry handbags Replica on
1/5/2010 10:56 PM
|
Re: Custom .NET –> COM Interop
gucci shoes, gucci handbags, gucci handbags
By ugg boots sale on
3/2/2010 9:52 PM
|
Re: Custom .NET –> COM Interop
if you want to buyin 2010 change you image, here is some good Website for more:
jordan shoes there were a good web for , you don't like, Never mind, much more
By gucci shoes on
3/10/2010 10:00 PM
|
Re: Custom .NET –> COM Interop
thank you for your great post, and I did want to share this. I hope you will also like it, if you think it is spamming, please kindly delete it. thank you!abercrombie see what is this? abercrombie and fitch uk abercrombie and fitch abercrombie fitch uk abercrombie mens abercrombie london
By abercrombie on
3/11/2010 6:29 AM
|
|
|
|
|
ed hardy
ED Hardy Hoodies ED Hardy Hoodies Ed Hardy Swimwear Ed Hardy Swimwear ed hardy tops ed hardy tops ed hardy shoes ed hardy shoes ed hardy t shirt ed hardy t shirt ed hardy shirts ed hardy shirts christian audigier christian audigier ed hardy kids ed hardy kids Ed Hardy Sunglasses Ed Hardy Sunglasses ED Hardy belts ED Hardy belts ed hardy Bags ed hardy Bags ed hardy purse ed hardy purse ed hardy mens ed hardy mens ed hardy womens d hardy womens ed hardy mens shirts ed hardy mens shirts ed hardy mens tops ed hardy mens tops ed hardy mens hoodies d hardy mens hoodies ed hardy mens swim trunks ed hardy mens swim trunks ed hardy mens shoes ed hardy mens shoes ed hardy womens swimwear ed hardy womens swimwear ed hardy womens t shirt ed hardy womens t shirt ed hardy womens tops ed hardy womens tops ed hardy womens pants ed hardy womens pants ed hardy womens hoodies ed hardy womens hoodies ed hardy womens shoes ed hardy womens shoes ed hardy womens clothing ed hardy womens clothing
By ed hardy on
3/15/2010 9:25 PM
|
cheap nike shox
There are wide variety of Nike Shox for both men and women's selection.The Nike Shox Sale are best selling nowadays.Get your own Cheap Nike Shox now.It's definitely time for you to buy womens nike shox and wens nike shox, Wearing them will keep you in a perfect condition.
By nike shox on
3/16/2010 10:17 PM
|
|
|
|