如何正确地将 VB-Script 数组与用 C# 编写的 COM 组件进行编组 [英] How to correctly marshal VB-Script arrays to and from a COM component written in C#

查看:13
本文介绍了如何正确地将 VB-Script 数组与用 C# 编写的 COM 组件进行编组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 C# (.Net 4.0) 构建一个 COM 对象,用于经典的 asp 站点.现在我想知道在组件和 asp 站点之间来回编组 VB-Script 数组(单维和多维)的正确方法是什么?代码示例将不胜感激.

I'm building a COM object in C# (.Net 4.0) to be used in an classic asp site. Now I'd like to know what's the proper way to marshal VB-Script arrays (single and multidimensional) back and forth between the component and the asp site? A code sample would be highly appreciated.

推荐答案

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

VBScript only likes to handle SAFEARRAY's that contain VARIANTS. And it likes to have these passed arround in VARIANTS on the COM methods or properties. So you need to construct a VARIANT property that contains a SAFEARRAY of VARIANT type. The following C# code does this. First using just a plain array of objects and then also showing we can cast an array of any other managed type into an array of objects such that the marshalling code will convert this into a SAFEARRAY of VARIANTs for us.

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(); } }
    }
}

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

This can be tested using the following 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

您可以看到此处报告的类型为 Variant() - 即:变体数组.

You can see the type reported here as Variant() - ie: an array of variants.

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

这篇关于如何正确地将 VB-Script 数组与用 C# 编写的 COM 组件进行编组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆