示例#1
0
        /// <summary>
        /// Generic marshalling function to retrieve structs from libvlc by reading from unmanaged memory with offsets
        /// This supports uint libvlc signatures.
        /// </summary>
        /// <typeparam name="T">Internal struct type</typeparam>
        /// <typeparam name="TU">publicly facing struct type</typeparam>
        /// <param name="nativeRef">native reference of the parent</param>
        /// <param name="getRef">Native libvlc call: retrieve collection start pointer from parent reference</param>
        /// <param name="retrieve">Retrieve the internal struct by marshalling the native pointer</param>
        /// <param name="create">Create a publicly facing struct from the internal struct values</param>
        /// <param name="releaseRef">Native libvlc call: release the array allocated with the getRef call with the given element count</param>
        /// <returns>An array of publicly facing struct types</returns>
        internal static TU[] Retrieve <T, TU>(IntPtr nativeRef, ArrayOut getRef, Func <IntPtr, T> retrieve,
                                              Func <T, TU> create, Action <IntPtr, uint> releaseRef)
            where T : struct
            where TU : struct
        {
            var  arrayPtr = IntPtr.Zero;
            uint count    = 0;

            try
            {
                count = getRef(nativeRef, out arrayPtr);
                if (count == 0)
                {
#if NETSTANDARD1_1 || NET40
                    return(new TU[0]);
#else
                    return(Array.Empty <TU>());
#endif
                }

                var resultList = new List <TU>();
                T   structure;

                for (var i = 0; i < count; i++)
                {
                    var ptr = Marshal.ReadIntPtr(arrayPtr, i * IntPtr.Size);
                    structure = retrieve(ptr);
                    var managedStruct = create(structure);
                    resultList.Add(managedStruct);
                }

                return(resultList.ToArray());
            }
            finally
            {
                if (arrayPtr != IntPtr.Zero)
                {
                    releaseRef(arrayPtr, count);
                    arrayPtr = IntPtr.Zero;
                }
            }
        }
示例#2
0
        /// <summary>
        /// Generic marshalling function to retrieve structs from libvlc by reading from unmanaged memory with offsets
        /// This supports uint libvlc signatures. This is used for the new mediatrack type which became a class.
        /// From libvlcsharp 4.0
        /// </summary>
        /// <typeparam name="T">publicly facing class type</typeparam>
        /// <param name="nativeRef">native reference of the parent</param>
        /// <param name="getRef">Native libvlc call: retrieve collection start pointer from parent reference</param>
        /// <param name="create">Create a publicly facing class from the ptr/internal struct values</param>
        /// <param name="releaseRef">Native libvlc call: release the array allocated with the getRef call with the given element count</param>
        /// <returns>An array of publicly facing class types</returns>
        internal static T[] Retrieve <T>(IntPtr nativeRef, ArrayOut getRef, Func <IntPtr, T> create, Action <IntPtr, uint> releaseRef)
            where T : class
        {
            var  arrayPtr = IntPtr.Zero;
            uint count    = 0;

            try
            {
                count = getRef(nativeRef, out arrayPtr);
                if (count == 0)
                {
#if NETSTANDARD1_1 || NET45
                    return(new T[0]);
#else
                    return(Array.Empty <T>());
#endif
                }

                var resultList = new List <T>();
                T   type;

                for (var i = 0; i < count; i++)
                {
                    var ptr = Marshal.ReadIntPtr(arrayPtr, i * IntPtr.Size);
                    type = create(ptr);
                    resultList.Add(type);
                }

                return(resultList.ToArray());
            }
            finally
            {
                if (arrayPtr != IntPtr.Zero)
                {
                    releaseRef(arrayPtr, count);
                    arrayPtr = IntPtr.Zero;
                }
            }
        }