Как передать тип данных массива вариантов VBA через COM-взаимодействие в метод C# - PullRequest
2 голосов
/ 20 марта 2020

В настоящее время я пытаюсь передать массив типов данных в метод c# через взаимодействие COM. Проблема заключается в том, что, передавая это как:

[MarshalAs(UnmanagedType.SafeArray)

Однако, похоже, это не работает, у кого-нибудь есть советы, как я могу передать это как параметр?

Вот мой полный c# источник:

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Reflection;

namespace ExpandExcel
{
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class ExpandExcelStandard
    {
        #region Public Static Methods

        [return: MarshalAs(UnmanagedType.SafeArray)]
        public static T[] RemoveDuplicates<T>([MarshalAs(UnmanagedType.SafeArray)] ref T[] arr)
        {
            // Creates a hash set based on arr
            HashSet<T> set = new HashSet<T>(arr);
            T[] resultArr = new T[set.Count];
            set.CopyTo(resultArr);
            return resultArr; // Return the resultArr
        }

        #endregion
    }
}

Вот мой полный источник VBA:

Sub main()
    Dim arr(1000000) As Variant

    Dim ExpandExcel As ExpandExcelStandard
    Set ExpandExcel = New ExpandExcelStandard

    For i = 0 To UBound(arr)
        Randomize
        arr(i) = Int((1000000 + 1) * Rnd)
    Next i

    Dim resultArr() As Variant

    resultArr = ExpandExcel.RemoveDuplicates(arr)
End Sub

1 Ответ

2 голосов
/ 20 марта 2020

Вы не можете использовать дженерики с COM, вы не можете использовать функции c и т.д. c. Вот аналогичный код, который должен работать:

VB

Sub main()
    Dim arr(1000000) As Variant

    For i = 0 To UBound(arr)
        Randomize
        arr(i) = Int((1000000 + 1) * Rnd)
    Next i

    Set ExpandExcel = CreateObject("ExpandExcelStandard") // I used late binding but early is fine too
    resultArr = ExpandExcel.RemoveDuplicates(arr)
End Sub

C#

[ProgId("ExpandExcelStandard")] // because I wanted late binding, I declared a progid
[ComVisible(true)]
public class ExpandExcelStandard
{
    // .NET object (w/o any Marshal spec) is passed as an automation Variant
    public object[] RemoveDuplicates(object[] arr) => new HashSet<object>(arr).ToArray();
}
...