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 -----Original Message----- From: Andrew Hopper [mailto:Andy.Hopper@;MINDSPRING.COM] Sent: Montag, 14. Oktober 2002 16:37 To: [EMAIL PROTECTED] Subject: Re: [ADVANCED-DOTNET] FW: Interop: Handling OUT parameter of array, gets error "Can not use SizeParamIndex for byref array parameters."?? Hello, Thomas- >From what I understand, using the SizeParamIndex to marshal arrays only works for marshaling data from managed code into COM and will not work for out parameters. Due to this, I'm afraid you won't be able to use the default marshaling provided by the framework. However, you should still be able to accomplish this task - it will simply require a little more work on your part. I would change the method declaration to be: ... // Eliminate PreserveSig unless you need to interpret the HRESULT /// <summary> /// The Next method retrieves a specified number of pins in the enumeration sequence /// </summary> /// <param name="cPins">Number of pins to retrieve</param> /// <param name="ppPins">Array of size cPins that is filled with IPin pointers</param> /// <param name="pcFetched">Pointer to a variable that receives the number of pins retrieved</param>void Next( // Pass the count we expect int cPins, // pass a pointer to a pointer that points to allocated memory ref IntPtr ppPins, // pass a pointer to an int that will be filled with the count out int pcFetched ); ... You would then have to wrap the method call in some helper code: // I'm assuming you already have obtained a pointer to // the IEnumPins interface and stored it in pEnum... IEnumPins pEnum; int numPins, cFetched, sizeOfIntPtr; IntPtr pPinArray = IntPtr.Zero, pPin; IPin[] arrayOfPins; try { // This is kind of anal - you could easily just use 4 instead of calculating // the size... sizeOfIntPtr = Marshal.SizeOf(typeof(IntPtr)); numPins = 42; //Put some real number here... // Allocate space to hold the array pPinArray = Marshal.AllocCoTaskMem[sizeOfIntPtr * numPins]; // Fill the array pEnum.Next(numPins, ref pPinArray, out cFetched); // Allocate space to hold the array of interfaces arrayOfPins = new IPin[cFetched]; // Load the array elements for(int counter = 0; counter < cFetched; counter++) { // nibble off an IntPtr at a time, // incrementing the offset as we go pPin = Marshal.ReadIntPtr(pPinArray, counter * sizeOfIntPtr); // convert the IntPtr to a managed pointer to an IPin arrayOfPins[counter] = (IPin)Marshal.GetObjectForIUnknown(pPin); } } finally { if(pPinArray != IntPtr.Zero) Marshal.FreeCoTaskMem(pPinArray); } // Do something with the array ... Hope this works (and helps)! -Andy Hopper -----Original Message----- From: Moderated discussion of advanced .NET topics. [mailto:ADVANCED-DOTNET@;DISCUSS.DEVELOP.COM] On Behalf Of Thomas Tomiczek Sent: Monday, October 14, 2002 6:49 AM To: [EMAIL PROTECTED] Subject: [ADVANCED-DOTNET] FW: Interop: Handling OUT parameter of array, gets error "Can not use SizeParamIndex for byref array parameters."?? > Hello, simple question (so to say). > > I ham trying to manage interoo for interface arrays. > > This interface definition is not working. It is for a DirectShow > Interface: > > [ComVisible(true), ComImport, > Guid("56a86892-0ad4-11ce-b03a-0020af0ba770"), > InterfaceType( ComInterfaceType.InterfaceIsIUnknown )] > public interface IEnumPins { > [PreserveSig] > int Next( > [In] int cPins, > [Out, MarshalAs(UnmanagedType.LPArray, > SizeParamIndex=2)] out IPin[] ppPins, > [Out] out int pcFetched ); > > [PreserveSig] > int Skip( [In] int cPins ); > void Reset(); > void Clone( [Out] out IEnumPins ppEnum ); > } > > When trying to use the next function, I get this error: > > An unhandled exception of type > 'System.Runtime.InteropServices.MarshalDirectiveException' occurred in > thonaconsulting.directshow.dll > Additional information: Can not use SizeParamIndex for byref > array parameters. > > That is sad, because I stop having clues on how to get this out. > Basically I try to get the next x pins. The 2nd parameter (index 1) > returns an array to the pints taken, and the third parameter returns > the number of pins put into the arrray. > > The error appears under .NET framework 1.1 - no way to check 1.0 > easly. > The stack trace shows that the error apears within the marshalling: at ThonaConsulting.DirectShow.IEnumPins.Next(Int32 cPins, IPin[]& ppPins, Int32& pcFetched) at ThonaConsulting.DirectShow.Utilities.FilterUtility.GetPin(IBaseFilter Filter, PinDirection Direction) in c:\work\thonaconsulting\directshow\thonaconsulting.directshow\utilities\ filterutility.cs:line 29 > Any clues? > > Thomas Tomiczek > THONA Consulting Ltd. > (Microsoft MVP C#/.NET) 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. You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.