Я создаю COM-объект в С# (.Net 4.0), который будет использоваться в классическом asp-сайте. Теперь я хотел бы знать, как правильно перемещать массивы VB- Script (одиночные и многомерные) между компонентом и сайтом asp? Образец кода будет высоко оценен.
Как правильно маршали массивы VB- Script в компонент COM, написанный на С#, и из него,
Ответ 1
VBScript только любит обрабатывать SAFEARRAY, содержащие VARIANTS. И он любит, чтобы они проходили arround в VARIANTS по методам или свойствам COM. Поэтому вам нужно построить свойство VARIANT, которое содержит тип SAFEARRAY of VARIANT. Следующий код С# делает это. Сначала используйте только простой массив объектов, а затем покажем, что мы можем отобразить массив любого другого управляемого типа в массив объектов, чтобы код маршаллинга преобразует это в SAFEARRAY of 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(); } }
}
}
Это можно протестировать с помощью следующего 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() - то есть: массив вариантов.
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
Ответ 2
Не столько ответ, сколько дополнительная информация:
Вот как можно использовать ответ patthoyts в классическом ASP, используя VBScript:
<%@Language=VBScript%>
<%
Dim o, v
Set o = CreateObject("StackOverflow.MyArrayDemo")
Response.Write "Count " & o.Count & " type: " & TypeName(o.Data) & " names: " & TypeName(o.Names)
For Each v in o.Data
Response.Write "<br />" & v
Next
For Each v in o.Names
Response.Write "<br />" & v
Next
%>
Я не могу получить доступ к отдельным элементам массива (например, o.Names(2)), что указывает на то, что он не является массивом, а больше похож на коллекцию.
Версия JScript:
<%@Language=JScript%>
<%
var o, v;
o = Server.CreateObject("StackOverflow.MyArrayDemo")
Response.Write ("Count " + o.Count + " type: " + (typeof o.Data) + " names: " + (typeof o.Names));
var a = o.Data.toArray();
for (v=0; v<a.length; v++)
Response.Write ("<br />" + a[v]);
var b = o.Names.toArray();
for (v=0; v<b.length; v++)
Response.Write ("<br />" + b[v]);
%>