2011-02-22 4 views
13

私は、古典的なaspサイトで使用するためにC#(.Net 4.0)でCOMオブジェクトを構築しています。今、コンポーネントとASPサイトの間でVBスクリプト・アレイ(単一および多次元)を前後にマーシャリングする適切な方法は何ですか?コードサンプルが高く評価されます。C#で書かれたCOMコンポーネントとの間でVBスクリプト配列を正しくマーシャリングする方法

答えて

17

VBScriptは、VARIANTSを含むSAFEARRAYを処理するのが好きです。そして、COMメソッドまたはプロパティのバリアントにこれらの渡されたarroundを持つのが好きです。したがって、VARIANT型のSAFEARRAYを含む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(); } } 
    } 
} 

この

は、次の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

バリアント()としてここに報告種類見ることができます - すなわち:バリアントの配列を。

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

は:「文字列が[]」「キャスト」の定義との最初の引数を受け入れていない拡張メソッド「キャスト」を含んでいません – Graham

+0

'Cast'メソッドはSystem.Linq名前空間で提供され、System.Coreアセンブリで提供されています(http://を参照してください)。 msdn.microsoft.com/en-us/library/bb341406.aspx)ので、既定のプロジェクトに必要なすべての参照が必要です。私のプロジェクトのコピーには、System、System.Core、Microsoft.CSharpの参照があります。使用ブロックは上記のとおりです。私はVisual Studio 2010でこれを作成しましたが、2008年も大丈夫です。 – patthoyts

+0

私の参照には、これらの3つが含まれ、System.Xml.Linqも含まれています。 2010年を使用しています。これらの3つだけの参照を減らして、そこにはまだエラーがあります。 – Graham

2

答えが、いくつかの追加情報があまりない:(

<%@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 
%> 

私は、個々の配列要素にアクセスすることはできません。

これは、VBScriptを使用してクラシックASPでpatthoyts'答えを消費する方法ですo.Names(2))は、配列ではなくコレクションのように機能することを示します。

JScriptのバージョン:mNames.Castラインで次のエラーを取得

<%@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]); 
%> 
関連する問題