2011-02-22 3 views

Respuesta

17

A VBScript solo le gusta manejar los SAFEARRAY que contienen VARIANTES. Y le gusta tener estos últimos en VARIANTS en los métodos o propiedades COM. Entonces, necesita construir una propiedad VARIANT que contenga un tipo SAFEARRAY de VARIANT. El siguiente código C# hace esto. Primero, utilizando solo una matriz simple de objetos y luego mostrando que podemos convertir una matriz de cualquier otro tipo gestionado en una matriz de objetos, de modo que el código de clasificación lo convierta en una SAFEARRAY de VARIANTES para nosotros.

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

Esto se puede probar utilizando la siguiente 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

Se puede ver el tipo informado aquí como Variant() - es decir: una matriz de variantes.

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

recibiendo el siguiente error en la línea mNames.Cast: 'string []' no contiene una definición de 'Fundido' y ningún método de extensión 'Fundido' aceptar un primer argumento de tipo 'string []' podría encontrarse (¿falta una directiva using o una referencia de ensamblado?) – Graham

+0

El método 'Cast 'se proporciona en el espacio de nombres System.Linq y se proporciona en el ensamblado System.Core (consulte http: // msdn.microsoft.com/en-us/library/bb341406.aspx) por lo que un proyecto predeterminado debe tener todas las referencias que necesita. Mi copia del proyecto tiene referencias para System, System.Core y Microsoft.CSharp y nada más. El bloque de uso es como se muestra arriba. Construí esto con Visual Studio 2010 pero 2008 también debería estar bien. – patthoyts

+0

Mis referencias incluyen esos tres y también System.Xml.Linq, entre otros. Estoy usando 2010. Ha reducido las referencias a solo esos 3 y el error sigue ahí. – Graham

2

No tanto una respuesta, pero alguna información adicional:

Esta es la forma de consumir respuesta patthoyts' en el clásico ASP con 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 
%> 

No puedo acceder a los elementos de la matriz (por ejemplo, o.Names (2)) que indica que no es una matriz sino que actúa más como una colección. Versión

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]); 
%> 
Cuestiones relacionadas