I came across the same problem with C-style arrays only last week. I solved
it the same way.

I have been getting some very odd behavior though -
ExecutionEngineExceptions and other random exceptions (even exceptions which
claim I am unable to write to the EventLog, which is patently false). So,
reluctantly, I've decided to write an unmanaged proxy which converts a
C-style array method into a SafeArray.


Regards,
Richard

> -----Original Message-----
> From: Moderated discussion of advanced .NET topics.
> [mailto:[EMAIL PROTECTED]]On Behalf Of Andrew Hopper
> Sent: 14 October 2002 15: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:[EMAIL PROTECTED]] 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.

Reply via email to