I changed the subject to reflect the new thread direction. Defining every method shouldn't be too bad, IFilter[1] is a fairly small interface. I wrote up some test code based off c++ code I found on google[2].
IFilter filter = null; string file = "C:\\temp\\test.doc"; int hresult; hresult = Loader.LoadIFilter(file, new IntPtr(0), out filter); IntPtr uflags; filter.Init( IFILTER_INIT.IFILTER_INIT_CANON_PARAGRAPHS |IFILTER_INIT.IFILTER_INIT_CANON_HYPHENS |IFILTER_INIT.IFILTER_INIT_CANON_SPACES |IFILTER_INIT.IFILTER_INIT_APPLY_INDEX_ATTRIBUTES |IFILTER_INIT.IFILTER_INIT_INDEXING_ONLY , 0, null, out uflags); STAT_CHUNK statChunk; hresult = filter.GetChunk(out statChunk); string test; uint sz = 1024; hresult = filter.GetText(out sz, out test); on the last line (GetText), the program exits, no error code is returned, the code just quits and I'm back in the IDE. The hresult from the GetChuck call is 0, so I assumed that everything was working fine to that point. Could someone take a look at this and see if anything pops out as being incorrect? The header file is in filter.h. While I haven't defined all the methods on IFilter yet, I'm not calling anything aside from the ones defined. [Flags] public enum IFILTER_INIT { IFILTER_INIT_CANON_PARAGRAPHS = 1, IFILTER_INIT_HARD_LINE_BREAKS = 2, IFILTER_INIT_CANON_HYPHENS = 4, IFILTER_INIT_CANON_SPACES = 8, IFILTER_INIT_APPLY_INDEX_ATTRIBUTES = 16, IFILTER_INIT_APPLY_CRAWL_ATTRIBUTES = 256, IFILTER_INIT_APPLY_OTHER_ATTRIBUTES = 32, IFILTER_INIT_INDEXING_ONLY = 64, IFILTER_INIT_SEARCH_LINKS = 128, IFILTER_INIT_FILTER_OWNED_VALUE_OK = 512 } public enum CHUNK_BREAKTYPE { CHUNK_NO_BREAK = 0, CHUNK_EOW = 1, CHUNK_EOS = 2, CHUNK_EOP = 3, CHUNK_EOC = 4 }; [Flags] public enum CHUNKSTATE { CHUNK_TEXT = 0x1, CHUNK_VALUE = 0x2, CHUNK_FILTER_OWNED_VALUE = 0x4 }; [StructLayout(LayoutKind.Explicit)] public struct PROPSPEC { [FieldOffset(0)] UInt32 ulKind; [FieldOffset(4)] UInt32 propid; [FieldOffset(4)] IntPtr lpwstr; }; [StructLayout(LayoutKind.Sequential)] public struct FULLPROPSPEC { Guid guidPropSet; PROPSPEC psProperty; }; [StructLayout(LayoutKind.Sequential)] public struct STAT_CHUNK { UInt32 idChunk; CHUNK_BREAKTYPE breakType; CHUNKSTATE flags; Int32 locale; FULLPROPSPEC attribute; UInt32 idChunkSource; UInt32 cwcStartSource; UInt32 cwcLenSource; } [ComVisible(true)] [Guid("89BCB740-6119-101A-BCB7-00DD010655AF")] [CLSCompliant(false)] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IFilter { [PreserveSig] int Init( [MarshalAs(UnmanagedType.U4)] IFILTER_INIT grfFlags, UInt32 cAttributes, [MarshalAs(UnmanagedType.LPArray)] FULLPROPSPEC[] aAttributes, out IntPtr pdwFlags ); [PreserveSig] int GetChunk( [MarshalAs(UnmanagedType.Struct)] out STAT_CHUNK pStat ); [PreserveSig] int GetText( [MarshalAs(UnmanagedType.U4)] out UInt32 pcwcBuffer, [MarshalAs(UnmanagedType.LPWStr)] out string awcBuffer ); } public class Loader { [DllImport("query.dll")] public static extern int LoadIFilter( [MarshalAs(UnmanagedType.LPWStr)] string pwcsPath, IntPtr pUnkOuter, [MarshalAs(UnmanagedType.Interface)] out IFilter ppIUnk ); } Thanks, Erick [1] ms-help://MS.VSCC/MS.MSDNVS/indexsrv/ixrefint_9sfm.htm [2] http://groups.google.com/groups?hl=en&safe=off&selm=uX4a1upoAHA.1708%40tkmsf tngp04 ----- Original Message ----- From: "Peter Stephens" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Monday, May 13, 2002 4:57 PM Subject: Re: [DOTNET] Using IFilter interface from C# > If you are calling an external IUnknown interface, then you will need to > define every method that procedes the methods you will call. You must define > the methods in the order in which they appear in the IDL or .H file, not in > the order they appear in the documentation (which is usually alphabetized). > > If the external COM component is calling your interface, then you will want > to define every method, because you never know which methods the external > component will call. > > As a rule of thumb, I always define every method to eliminate one more > potential cause of interop failure. > > Note that you must not define the IUnknown methods. These will be provided > by the CLR. > > You will probably want to look at the Docs for Marshaling data [1]. Examples > for marshaling structures that point to other structures are here: [2]. > > -- > Peter > > [1] > http://msdn.microsoft.com/library/en-us/cpguide/html/cpconmarshalingdatawith > platforminvoke.asp?frame=true > > [2] > http://msdn.microsoft.com/library/en-us/cpguide/html/cpconstructssample.asp? > frame=true > > > Erick Thompson spake: > > > > After beating around a number of bushes, I've decided to jump into interop > > with both feet. So, I'm trying to put together code to let me use IFilter > > via LoadIFilter. Do I need to write RCW method signatures for all the > > methods of an interface, or only the ones I am interested > > in/going to call? > > > > Thanks, > > Erick > > > > ----- Original Message ----- > > From: "Peter Stephens" <[EMAIL PROTECTED]> > > To: <[EMAIL PROTECTED]> > > Sent: Thursday, May 09, 2002 3:05 PM > > Subject: Re: [DOTNET] Using IFilter interface from C# > > > > > > > > Erick Thompson spake: > > > > > > > > How would I go about using the IFilter[1] interface from C#? > > From what I > > > > gather, it's not an automation interface (== not a COM object?), > > > > so I'm not > > > > sure where to start. > > > > > > > > Thanks, > > > > Erick > > > > > > > > [1] > > > > http://msdn.microsoft.com/library/default.asp?url=/library/en-us/i > > > ndexsrv/ixrefint_9sfm.asp > > > > > > > > > If there is a type library, you could use the tlbimp utility to > > generate a > > > proxy assembly. > > > > > > If there is no type library, you can create your own Runtime Callable > > > Wrappers (RCWs). > > > > > > Here is an RCW for IClassFactory: > > > > > > ===> > > > [ComVisible(true)] > > > [Guid("00000001-0000-0000-c000-000000000046")] > > > [CLSCompliant(false)] > > > [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] > > > public interface IClassFactory > > > { > > > [PreserveSig] > > > Int32 CreateInstance( > > > IntPtr pUnkOuter, > > > [In] ref Guid refiid, > > > IntPtr ppvObject); > > > void LockServer( > > > [MarshalAs(UnmanagedType.Bool)] Boolean fLock); > > > } > > > <=== > > > > > > And here is an RCW for IPersistStreamInit: > > > ===> > > > [ComVisible(true)] > > > [Guid("7fd52380-4e07-101b-ae2d-08002b2ec713")] > > > [CLSCompliant(false)] > > > [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] > > > public interface IPersistStreamInit > > > { > > > void GetClassID(out Guid pClassID); > > > [PreserveSig] > > > Int32 IsDirty(); > > > void Load(IStream stream); > > > void Save(IStream stream, > > [MarshalAs(UnmanagedType.Bool)] Boolean > > > fClearDirty); > > > UInt64 GetSizeMax(); > > > void InitNew(); > > > } > > > <=== > > > > > > If you call a DLL routine to get your interface pointer, setup your > > p/invoke > > > as follows: > > > // P/Invoke functions > > > [DllImport("urlmon.dll")] > > > private static extern Int32 CoInternetGetSession( > > > UInt32 dwSessionMode, > > > ref IInternetSession ppIInternetSession, > > > UInt32 dwReserved); > > > > > > -- > > > Peter > > You can read messages from the DOTNET archive, unsubscribe from DOTNET, or > subscribe to other DevelopMentor lists at http://discuss.develop.com. > You can read messages from the DOTNET archive, unsubscribe from DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.