[EMAIL PROTECTED] schrieb: > Hello, > > I am working with comtypes to interface Microsoft's DirectShow library.
Cool, another one using comtypes! > First, I found a Type Library on the internet that was created for > accessing DirectShow from .NET. It seems that DirectShow only comes > with IDL files and no type library. What I sometimes do is to compile the IDL files into a typelib just for creating the comtypes interface wrappers. This may be somewhat dangerous because these typelibs should *not* be registered by accident, so that they do not conflict with other typelibs. Then, I found out with oleview that on my system the IMediaControl interface is described in the 'ActiveMovie control type library (Ver 1.0)', in c:\windows\system32\quartz.dll. So I was able to create the wrapper by calling comtypes.client.GetModule("quartz.dll") - it seems that windows searches the $PATH to find type libraries. > This got me started. > > The following line imports the typelibrary and automatically generates > a wrapper module for DirectShow. > > ds = comtypes.client.GetModule('DirectShow.tlb') > > Next, I can basically start with something like this: > > graph = comtypes.CoCreateInstance(CLSID_FilterGraph, ds.IGraphBuilder, > comtypes.CLSCTX_INPROC_SERVER) > > I had to create the CLSID_FilterGraph parameter myself by doing the > following: > > CLSID_FilterGraph = > comtypes.GUID('{e436ebb3-524f-11ce-9f53-0020af0ba770}') > > One of the first issues I ran into was that the type library I found on > the web didn't expose the IMediaControl interface. So, using the > generated wrapper as a template, I created my own wrapper: > > class IMediaControl(comtypes.IUnknown): > _case_insensitive_ = True > _iid_ = comtypes.GUID('{56A868B1-0AD4-11CE-B03A-0020AF0BA770}') > _idlflags_ = [] > IMediaControl._methods_ = [ > COMMETHOD([], HRESULT, 'Run'), > COMMETHOD([], HRESULT, 'Pause'), > COMMETHOD([], HRESULT, 'Stop'), > COMMETHOD([], HRESULT, 'StopWhenReady'), > COMMETHOD([], HRESULT, 'GetState', > (['in'], c_long, 'msTimeout'), > (['out'], POINTER(c_int), 'pfs' )) > ] > > This got me further. Once I defined the interface, I get access to the > interface by calling: > > control = graph.QueryInterface(IMediaControl) > > This seemed to work. Once I got everything setup, I tried to use this > interface. For example: > > control.Run() > > This generates an exception: > > Traceback (most recent call last): > File "<stdin>", line 1, in ? > File "ds.py", line 462, in play > control.Run() > ValueError: Procedure probably called with not enough arguments (4 > bytes missing) > > You can get errors like this when using ctypes if you use the wrong > calling convention (CDLL versus WINDLL). > > The method "Run" on the IMediaControl interface doesn't take any > arguments. > > I did notice that some wrapper code uses STDMETHOD versus COMMETHOD, > but changing this didn't make any difference. > > Can anyone explain what might be happening here, or offer some > suggestions? Your mistake here is that IMediaControl derives from IDispatch, not IUnknown. So, control.Run() really calls the first IDispatch method, which is GetTypeInfoCount(), which takes one argument ;-). I'm not 100% sure the following code will work for you because I'm using a comtypes version that's not yet committed to the repository, but it works for me: from comtypes.client import GetModule, CreateObject # create and import the interface wrapper ds = GetModule("quartz.dll") # FilgraphManager is what the wrapper shows as coclass, # you can pass that to CreateObject instead of a CLSID or ProgID. # CreateObject calls QueryInterface for the 'most useful' interface, # so usually there's no need to specify the interface you want: fg = CreateObject(ds.FilgraphManager) # this prints '0' print fg.Run() Thomas -- http://mail.python.org/mailman/listinfo/python-list