如何通过COM将VB6中的长数组传递到C#?

6

我需要将一个int或long数组(无所谓)从VB6应用程序传递给一个C# COM Visible类。我尝试在C#中声明接口,如下所示:

void Subscribe([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_I4)]int[] notificationTypes)

void Subscribe(int[] notificationTypes)

但两者都引发了一个错误:函数或接口被标记为受限制,或该函数使用 Visual Basic 不支持的自动化类型

我应该如何声明 C# 方法呢?


这很奇怪。只需删除[MarshalAs],该数组已经作为SAFEARRAY驻留,不需要您的帮助。如果仍然遇到问题,我们需要看到接口类型的其余部分。 - Hans Passant
@HansPassant 是的,我查看了生成的IDL,它在两种情况下都被正确声明为SAFEARRAY(long),所以我认为这可能与VB6有关的问题。我还在调查中。 - Ignacio Soler Garcia
这个回答解决了你的问题吗?使用COM互操作从VBA将数组传递到C# - GSerg
@GSerg 老实说,我是9年前提出这个问题的,很久以前就不再从事这些技术了。不过这个答案看起来不错。 - Ignacio Soler Garcia
1
@IgnacioSolerGarcia 没问题,这不仅是回答你的问题,还将这些问题联系在一起,为未来的读者提供帮助。 - GSerg
2个回答

1
如果你感到绝望,可以在一个虚拟的VB6 ActiveX dll项目中编写签名。然后通过Visual Studio或命令行工具生成vb6组件的.NET互操作版本。然后使用Reflector或dotPeek从互操作程序集中提取代码。这是一种比较麻烦的方法,但它是可行的。

-1

我在9年后遇到了这个问题。我想出的解决方案是传递一个指向数组第一个元素的指针,以及上限(在VB6中称为UBound)。然后迭代指针到上限,并将每个元素放入列表中。

在VB6端使用:

    Dim myarray(3) As float
    Dim ptr As integer
    Dim upperbound as integer

    myarray(0) = 0.1
    myarray(1) = 0.2
    myarray(2) = 0.3
    myarray(3) = 0.4

    ptr = VarPtr(myarray(0))
    upperbound = UBound(myarray)

    SetMyFloat(ptr, upperbound)
    

C# 代码


    public float MyFloat {get; set;}

    public unsafe void SetMyFloat(float* ptr, int ubound)
    {
        MyFloat = PointerToFloatArray(ptr, ubound);
    }

    public unsafe float[] PointerToFloatArray(float* ptr, int ubound)
    //this is to deal with not being able to pass an array from vb6 to .NET
    //ptr is a pointer to the first element of the array
    //ubound is the index of the last element of the array
    {
        List<float> li = new List<float>();
        float element;
        for (int i = 0; i <= ubound; i++)
        {
            element = *(ptr + i);
            li.Add(element);
        }
        return li.ToArray();
    }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接