2011-02-22 10 views

risposta

17

A VBScript piace solo gestire SAFEARRAY che contengono VARIANTI. E gli piace avere questi passati in VARIANTI sui metodi o proprietà COM. Quindi è necessario costruire una proprietà VARIANT che contenga un SAFEARRAY di tipo VARIANT. Il seguente codice C# fa questo. Prima usiamo solo una semplice schiera di oggetti e poi mostriamo che possiamo lanciare una matrice di qualsiasi altro tipo gestito in una matrice di oggetti, in modo che il codice di marshalling lo converta in un SAFEARRAY di VARIANTI per noi.

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

Questo può essere testata usando il seguente 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

È possibile vedere il tipo riportato qui come variante() - cioè: una matrice di varianti.

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
+0

ottenere il seguente errore sulla linea mNames.Cast: 'string []' non contiene una definizione per 'Fusioni' e nessun metodo di estensione 'Fusioni' accettare un primo argomento di è possibile trovare il tipo 'stringa []' (ti manca una direttiva using o un riferimento all'assembly?) – Graham

+0

Il metodo 'Cast' viene fornito nello spazio dei nomi System.Linq e fornito nell'assembly System.Core (vedere http: // msdn.microsoft.com/en-us/library/bb341406.aspx) quindi un progetto predefinito dovrebbe avere tutti i riferimenti necessari. La mia copia del progetto ha riferimenti per System, System.Core e Microsoft.CSharp e nient'altro. Il blocco usando è come mostrato sopra. L'ho creato con Visual Studio 2010 ma il 2008 dovrebbe essere ok. – patthoyts

+0

I miei riferimenti includono questi tre e anche System.Xml.Linq tra gli altri. Sto usando il 2010. Ho ridotto i riferimenti a solo quei 3 e l'errore ancora lì. – Graham

2

Non tanto una risposta, ma alcune informazioni aggiuntive:

Questo è il modo di consumare la risposta patthoyts' in Classic ASP utilizzando 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 
%> 

Non riesco ad accedere ai singoli elementi di array (ad esempio o.Nomi (2)) che indica che non è un array ma che agisce più come una raccolta. Versione

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]); 
%> 
Problemi correlati