コード例 #1
0
        public void SAFEARRAY_CreateSingleDimension_GetProperties_Success(ushort vt, ushort expectedFeatures, uint expectedCbElements)
        {
            var saBound = new SAFEARRAYBOUND
            {
                cElements = 10,
                lLbound   = 1
            };
            SAFEARRAY *psa = SafeArrayCreate((VARENUM)vt, 1, &saBound);

            Assert.True(psa != null);

            try
            {
                Assert.Equal(1u, psa->cDims);
                Assert.Equal((FADF)expectedFeatures, psa->fFeatures);
                Assert.Equal((uint)expectedCbElements, psa->cbElements);
                Assert.Equal(0u, psa->cLocks);
                Assert.True(psa->pvData != null);
                Assert.Equal(10u, psa->rgsabound[0].cElements);
                Assert.Equal(1, psa->rgsabound[0].lLbound);

                VARENUM arrayVt = VARENUM.EMPTY;
                HRESULT hr      = SafeArrayGetVartype(psa, &arrayVt);
                Assert.Equal(HRESULT.S_OK, hr);
                Assert.Equal((VARENUM)vt, arrayVt);
            }
            finally
            {
                HRESULT hr = SafeArrayDestroy(psa);
                Assert.Equal(HRESULT.S_OK, hr);
            }
        }
コード例 #2
0
ファイル: Interop.VARIANT.cs プロジェクト: tbolon/winforms
                static void HeapTransposeArray(SAFEARRAY *psa, Array array, VARENUM arrayType)
                {
                    var indices = new int[array.Rank];
                    var lower   = new int[array.Rank];
                    var upper   = new int[array.Rank];

                    InternalTransposeArray(psa, array, arrayType, indices, lower, upper);
                }
コード例 #3
0
ファイル: Interop.VARIANT.cs プロジェクト: tbolon/winforms
                static void StackTransposeArray(SAFEARRAY *psa, Array array, VARENUM arrayType)
                {
                    Span <int> indices = stackalloc int[array.Rank];
                    Span <int> lower   = stackalloc int[array.Rank];
                    Span <int> upper   = stackalloc int[array.Rank];

                    InternalTransposeArray(psa, array, arrayType, indices, lower, upper);
                }
コード例 #4
0
ファイル: Interop.VARIANT.cs プロジェクト: tbolon/winforms
 private static void TransposeArray(SAFEARRAY *psa, Array array, VARENUM arrayType)
 {
     if (array.Rank <= 32)
     {
         StackTransposeArray(psa, array, arrayType);
     }
     else
     {
         Debug.Fail("The CLR should not support arrays with more than 32 dimensions.");
         HeapTransposeArray(psa, array, arrayType);
     }
コード例 #5
0
        public void SAFEARRAY_CreateSingleDimensionRECORD_GetProperties_Success()
        {
            var saBound = new SAFEARRAYBOUND
            {
                cElements = 10,
                lLbound   = 1
            };
            var    record  = new CustomRecordInfo();
            IntPtr pRecord = Marshal.GetComInterfaceForObject <CustomRecordInfo, IRecordInfo>(record);

            try
            {
                SAFEARRAY *psa = SafeArrayCreateEx(VARENUM.RECORD, 1, &saBound, pRecord);
                Assert.True(psa != null);

                try
                {
                    Assert.Equal(1u, psa->cDims);
                    Assert.Equal(FADF.RECORD, psa->fFeatures);
                    Assert.Equal((uint)sizeof(int), psa->cbElements);
                    Assert.Equal(0u, psa->cLocks);
                    Assert.True(psa->pvData != null);
                    Assert.Equal(10u, psa->rgsabound[0].cElements);
                    Assert.Equal(1, psa->rgsabound[0].lLbound);

                    VARENUM arrayVt = VARENUM.EMPTY;
                    HRESULT hr      = SafeArrayGetVartype(psa, &arrayVt);
                    Assert.Equal(HRESULT.S_OK, hr);
                    Assert.Equal(VARENUM.RECORD, arrayVt);
                }
                finally
                {
                    HRESULT hr = SafeArrayDestroy(psa);
                    Assert.Equal(HRESULT.S_OK, hr);
                }
            }
            finally
            {
                Marshal.Release(pRecord);
            }
        }
コード例 #6
0
ファイル: Interop.VARIANT.cs プロジェクト: tbolon/winforms
                static void InternalTransposeArray(SAFEARRAY *psa, Array array, VARENUM arrayType, Span <int> indices, Span <int> lower, Span <int> upper)
                {
                    int lastIndex = array.Rank - 1;
                    int i;

                    for (i = 0; i < array.Rank; i++)
                    {
                        indices[i] = lower[i] = array.GetLowerBound(i);
                        upper[i]   = array.GetUpperBound(i);
                    }

                    // Loop through all the indices.
                    while (true)
                    {
BeginMainLoop:

                        SetArrayValue(psa, array, indices, lower, arrayType);

                        for (i = lastIndex; i > 0;)
                        {
                            if (++indices[i] <= upper[i])
                            {
                                goto BeginMainLoop;
                            }

                            indices[i] = lower[i];
                            --i;
                        }

                        // Special case for the first index, it must be enumerated only once
                        if (++indices[0] > upper[0])
                        {
                            break;
                        }
                    }
                }
コード例 #7
0
ファイル: Interop.VARIANT.cs プロジェクト: tbolon/winforms
            private static object?ToArray(SAFEARRAY *psa, VARENUM vt)
            {
                if (psa is null)
                {
                    return(null);
                }

                VARENUM arrayType = vt & ~VARENUM.ARRAY;
                Array   array     = CreateArrayFromSafeArray(psa, arrayType);

                HRESULT hr = SafeArrayLock(psa);

                Debug.Assert(hr == HRESULT.S_OK);

                try
                {
                    if (array.Rank == 1)
                    {
                        switch (arrayType)
                        {
                        case VARENUM.I1:
                            new Span <sbyte>(psa->pvData, array.Length)
                            .CopyTo(GetSpan <sbyte>(array));
                            break;

                        case VARENUM.UI1:
                            new Span <byte>(psa->pvData, array.Length)
                            .CopyTo(GetSpan <byte>(array));
                            break;

                        case VARENUM.I2:
                            new Span <short>(psa->pvData, array.Length)
                            .CopyTo(GetSpan <short>(array));
                            break;

                        case VARENUM.UI2:
                            new Span <ushort>(psa->pvData, array.Length)
                            .CopyTo(GetSpan <ushort>(array));
                            break;

                        case VARENUM.I4:
                        case VARENUM.INT:
                            new Span <int>(psa->pvData, array.Length)
                            .CopyTo(GetSpan <int>(array));
                            break;

                        case VARENUM.UI4:
                        case VARENUM.UINT:
                        case VARENUM.ERROR:     // Not explicitly mentioned in the docs but trivial to implement.
                            new Span <uint>(psa->pvData, array.Length)
                            .CopyTo(GetSpan <uint>(array));
                            break;

                        case VARENUM.I8:
                            new Span <long>(psa->pvData, array.Length)
                            .CopyTo(GetSpan <long>(array));
                            break;

                        case VARENUM.UI8:
                            new Span <ulong>(psa->pvData, array.Length)
                            .CopyTo(GetSpan <ulong>(array));
                            break;

                        case VARENUM.R4:
                            new Span <float>(psa->pvData, array.Length)
                            .CopyTo(GetSpan <float>(array));
                            break;

                        case VARENUM.R8:
                            new Span <double>(psa->pvData, array.Length)
                            .CopyTo(GetSpan <double>(array));
                            break;

                        case VARENUM.BOOL:
                        {
                            var data   = new Span <VARIANT_BOOL>(psa->pvData, array.Length);
                            var result = GetSpan <bool>(array);
                            for (int i = 0; i < data.Length; i++)
                            {
                                result[i] = data[i] != VARIANT_BOOL.FALSE;
                            }

                            break;
                        }

                        case VARENUM.DECIMAL:
                        {
                            var data   = new Span <DECIMAL>(psa->pvData, array.Length);
                            var result = GetSpan <decimal>(array);
                            for (int i = 0; i < data.Length; i++)
                            {
                                result[i] = data[i].ToDecimal();
                            }

                            break;
                        }

                        case VARENUM.CY:
                        {
                            var data   = new Span <long>(psa->pvData, array.Length);
                            var result = GetSpan <decimal>(array);
                            for (int i = 0; i < data.Length; i++)
                            {
                                result[i] = decimal.FromOACurrency(data[i]);
                            }

                            break;
                        }

                        case VARENUM.DATE:
                        {
                            var data   = new Span <double>(psa->pvData, array.Length);
                            var result = GetSpan <DateTime>(array);
                            for (int i = 0; i < data.Length; i++)
                            {
                                result[i] = DateTime.FromOADate(data[i]);
                            }

                            break;
                        }

                        case VARENUM.BSTR:
                        {
                            var data   = new Span <IntPtr>(psa->pvData, array.Length);
                            var result = GetSpan <string?>(array);
                            for (int i = 0; i < data.Length; i++)
                            {
                                result[i] = Marshal.PtrToStringUni(data[i]);
                            }

                            break;
                        }

                        case VARENUM.DISPATCH:
                        case VARENUM.UNKNOWN:
                        {
                            var data   = new Span <IntPtr>(psa->pvData, array.Length);
                            var result = GetSpan <object?>(array);
                            for (int i = 0; i < data.Length; i++)
                            {
                                if (data[i] == IntPtr.Zero)
                                {
                                    result[i] = null;
                                }
                                else
                                {
                                    result[i] = Marshal.GetObjectForIUnknown(data[i]);
                                }
                            }

                            break;
                        }

                        case VARENUM.VARIANT:
                        {
                            var data   = new Span <VARIANT>(psa->pvData, array.Length);
                            var result = GetSpan <object?>(array);
                            for (int i = 0; i < data.Length; i++)
                            {
                                result[i] = data[i].ToObject();
                            }

                            break;
                        }

                        case VARENUM.RECORD:
                            throw new NotImplementedException();

                        default:
                            throw new ArgumentException(string.Format(SR.COM2UnhandledVT, vt));
                        }
                    }
                    else if (array.Length != 0)
                    {
                        // CLR arrays are laid out in row-major order.
                        // See CLI 8.9.1: https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf
                        // However, SAFEARRAYs are laid out in column-major order.
                        // See https://docs.microsoft.com/en-us/previous-versions/windows/desktop/automat/array-manipulation-functions
                        // Therefore, we need to transpose data.
                        TransposeArray(psa, array, arrayType);
                    }
                }
                finally
                {
                    hr = SafeArrayUnlock(psa);
                    Debug.Assert(hr == HRESULT.S_OK);
                }

                return(array);
            }
コード例 #8
0
 public HRESULT put_BootImageOptionsArray(SAFEARRAY *newVal)
 {
     return(((delegate * unmanaged <IFileSystemImage2 *, SAFEARRAY *, int>)(lpVtbl[58]))((IFileSystemImage2 *)Unsafe.AsPointer(ref this), newVal));
 }
コード例 #9
0
 public HRESULT put_MultisessionInterfaces(SAFEARRAY *newVal)
 {
     return(((delegate * unmanaged <IFileSystemImage2 *, SAFEARRAY *, int>)(lpVtbl[56]))((IFileSystemImage2 *)Unsafe.AsPointer(ref this), newVal));
 }
コード例 #10
0
 public static unsafe partial HRESULT SafeArrayGetVartype(SAFEARRAY *psa, Ole32.VARENUM *pvt);
コード例 #11
0
 public int put_MultisessionInterfaces([NativeTypeName("SAFEARRAY *")] SAFEARRAY *newVal)
 {
     return(((delegate * unmanaged <IFileSystemImage3 *, SAFEARRAY *, int>)(lpVtbl[56]))((IFileSystemImage3 *)Unsafe.AsPointer(ref this), newVal));
 }
コード例 #12
0
 public unsafe static extern HRESULT SafeArrayLock(SAFEARRAY *psa);
コード例 #13
0
 public unsafe static extern HRESULT SafeArrayGetVartype(SAFEARRAY *psa, Ole32.VARENUM *pvt);
コード例 #14
0
 public unsafe static extern HRESULT SafeArrayGetRecordInfo(SAFEARRAY *psa, out IRecordInfo pRecInfo);
コード例 #15
0
 public static unsafe partial HRESULT SafeArrayUnlock(SAFEARRAY *psa);
コード例 #16
0
 public int put_BootImageOptionsArray([NativeTypeName("SAFEARRAY *")] SAFEARRAY *newVal)
 {
     return(((delegate * unmanaged <IFileSystemImage3 *, SAFEARRAY *, int>)(lpVtbl[58]))((IFileSystemImage3 *)Unsafe.AsPointer(ref this), newVal));
 }
コード例 #17
0
ファイル: Interop.VARIANT.cs プロジェクト: tbolon/winforms
 private static void SetArrayValue(SAFEARRAY *psa, Array array, Span <int> indices, Span <int> lowerBounds, VARENUM arrayType)
 {
コード例 #18
0
 public unsafe static extern uint SafeArrayGetElemsize(SAFEARRAY *psa);