Thanks a lot Andrew, but there is one thing I dont get here... void Next(int cPins, [MarshalAs(UnmanagedType.LPArray)] IntPtr[] ppPins, out int pcFetched);
and pinArray = new IntPtr[size]; pinEnum.Next(size, pinArray, out fetched); Does the Marshaller trust me that the size in pinArray is big enough? I mean, if I work with my unmanaged code blocks, then he has no choice, but here - he can hardly know where the stuff is written in the croutine called. Thomas Tomiczek THONA Consulting Ltd. (Microsoft MVP C#/.NET) -----Original Message----- From: Andrew Hopper [mailto:Andy.Hopper@;MINDSPRING.COM] Sent: Samstag, 19. Oktober 2002 14:38 To: [EMAIL PROTECTED] Subject: Re: [ADVANCED-DOTNET] FW: Interop: Handling OUT parameter of array, gets error "Can not use SizeParamIndex for byref array parameters."?? Thomas- If the value of size changed something went terribly wrong, and I wouldn't expect any code past the Next() call to work. I'd first try removing the int return value - without the PreserveSig attribute, the runtime will think the method has a fourth [out, retval] parameter. I'd also remove the [In] and [In, Out] attributes from the parameters. Parameters are in by default and the ref and out keywords act like implicit [In, Out] and [Out] attributes, respectively. I've also learned a slightly "better" way to marshal an array of pointers that requires less code. It's a little shorter, and doesn't require you to allocate unmanaged memory (always a good thing). I suggest that you try this approach: public interface IEnumPins { void Next(int cPins, [MarshalAs(UnmanagedType.LPArray)] IntPtr[] ppPins, out int pcFetched); ... } public static IPin [] GetPins(IBaseFilter Filter) { int size = 32; IntPtr[] pinArray = null; int fetched = 0; IPin [] pins = null; IEnumPins pinEnum = null; try { pinArray = new IntPtr[size]; Filter.EnumPins( out pinEnum ); pinEnum.Next(size, pinArray, out fetched); pins = new IPin[fetched]; for (int i = 0; i < fetched; i++) { pins [i] = (IPin)Marshal.GetObjectForIUnknown(pinArray[i]); } } finally { if (pinEnum != null) { Marshal.ReleaseComObject (pinEnum); } } return pins; } I understand your frustration with this part of COM interop, but it's really not so bad. Passing arrays (and structs that contain pointers to arrays) just happens to be the hardest part to master. -Andy -----Original Message----- From: Moderated discussion of advanced .NET topics. [mailto:ADVANCED-DOTNET@;DISCUSS.DEVELOP.COM] On Behalf Of Thomas Tomiczek Sent: Friday, October 18, 2002 4:47 AM To: [EMAIL PROTECTED] Subject: Re: [ADVANCED-DOTNET] FW: Interop: Handling OUT parameter of array, gets error "Can not use SizeParamIndex for byref array parameters."?? Andrew - I hve to ge this back up. Found the time to try it out today, but it breaks. This is the interface I have now (part of, only): public interface IEnumPins { int Next( [In] int cPins, [In, Out] ref IntPtr ppPins, out int pcFetched); And this is my code- basically a copy of your code trying to get the first 32 pins. public static IPin [] GetPins (IBaseFilter Filter) { int size = 32; IntPtr pPinArrayUM = IntPtr.Zero; int fetched = 0; IPin [] pins = new IPin [0]; IEnumPins pinEnum = null; try { int ptrsize = Marshal.SizeOf(typeof(IntPtr)); pPinArrayUM = Marshal.AllocCoTaskMem (size * ptrsize); Filter.EnumPins( out pinEnum ); pinEnum.Next (size, ref pPinArrayUM, out fetched); pins = new IPin [fetched]; for (int i = 0; i < fetched; i++) { IntPtr pPin = Marshal.ReadIntPtr (pPinArrayUM, i*ptrsize); pins [i] = (IPin) Marshal.GetObjectForIUnknown (pPin); } } finally { if (pinEnum != null) { Marshal.ReleaseComObject (pinEnum); } if (pPinArrayUM != IntPtr.Zero) { Marshal.FreeCoTaskMem (pPinArrayUM); } } return pins; } I get the following erroneus behavior when single stepping: (a) after calling the pinEnum.Next function, the debugger changes the values shown for pPinArrayUM AND size - they change both their values to something pretty high. Looks like the pointers are being overwritten. (b) when continuing, the followng error happens at the first GetObjectForIUnknown: Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object. at System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(IntPtr pUnk) at ThonaConsulting.DirectShow.Utilities.FilterUtility.GetPins(IBaseFilter Filter) in c:\work\thonaconsulting\directshow\thonaconsulting.directshow\utilities\ filterutility.cs:line 31 This looks very much like the data is being written to the wrong areas upon return. I am pretty sure it is a totally stupid error, but I dont find it. I just wish, interop would be more powerfull. Thomas You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com. You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.