如何正确编组VB脚本数组与用C#编写的COM组件编组

Mat*_*ats 14 .net arrays com-interop marshalling asp-classic

我正在C#(.NET 4.0)中构建一个COM对象,用于经典的asp站点.现在我想知道在组件和asp站点之间来回编组VB脚本数组(单维和多维)的正确方法是什么?代码示例将受到高度赞赏.

pat*_*yts 18

VBScript只喜欢处理包含VARIANTS的SAFEARRAY.它喜欢在COM方法或属性上将这些传递给VARIANTS中的arround.因此,您需要构造一个包含SAFEARRAY VARIANT类型的VARIANT属性.以下C#代码执行此操作.首先只使用一个普通的对象数组,然后还显示我们可以将任何其他托管类型的数组转换为一个对象数组,这样编组代码就可以为我们将其转换为一个SAFEARRAY的VARIANT.

using System;
using System.Runtime.InteropServices;
using System.Linq;

namespace StackOverflow
{
    [ComVisible(true)]
    [Guid("2F4C19A6-9BB9-4ACF-90D1-BAF48696740A")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface IMyArrayDemo
    {
        [DispId(1)]
        int Count
        {
            [return: MarshalAs(UnmanagedType.I4)]
            get;
        }
        [DispId(2)]
        object Data
        {
            [return: MarshalAs(UnmanagedType.Struct, SafeArraySubType = VarEnum.VT_ARRAY)]
            get;
        }
        [DispId(3)]
        object Names
        {
            [return: MarshalAs(UnmanagedType.Struct, SafeArraySubType = VarEnum.VT_ARRAY)]
            get;
        }
    }

    [ComVisible(true)]
    [Guid("7EF75834-22BE-4861-879B-EA0CE20E46E9")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("StackOverflow.MyArrayDemo")]
    public class MyArrayDemo : IMyArrayDemo
    {
        object[] mData = new object[10] { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 };
        string[] mNames = new string[5] {"one", "two", "three", "four", "five"};
        public int Count { get { return mData.Length; } }
        public object Data { get { return mData; } }
        public object Names { get { return mNames.Cast<object>().ToArray(); } }
    }
}
Run Code Online (Sandbox Code Playgroud)

这可以使用以下vbscript进行测试:

Option Explicit
Sub Main
  Dim o, v
  Set o = CreateObject("StackOverflow.MyArrayDemo")
  WScript.Echo "Count " & o.Count & " type: " & TypeName(o.Data) & " names: " & TypeName(o.Names)
  For Each v in o.Data : WScript.Echo CStr(v) : Next
  For Each v in o.Names : WScript.Echo v : Next
End Sub
Main
Run Code Online (Sandbox Code Playgroud)

你可以看到这里报告的类型为Variant() - 即:一组变体.

C:\Users\pat>\windows\SysWOW64\cscript.exe -nologo arraytest.vbs
Count 10 type: Variant() names: Variant()
0
1
1
2
3
5
8
13
21
34
one
two
three
four
five