2012-05-07 15 views
1

私はInteropユーザーコントロール(VB.NET)を呼び出して、get/set呼び出しから複数の値を受け入れたいと考えています。私はユーザー定義型(UDT)を想定していましたが、正しい方法ですが、VB6コンパイルの「変数はVisual Basicでサポートされていないオートメーションタイプを使用しています。 InteropコントロールとVB6アプリケーション間で複数の値を渡す方法は?Interop呼び出しから複数の結果(UDT?)を返す - VB6 <--> VB.NET

VB.NET(相互運用)コード、.NETのListViewコントロール

Structure Employee 
    Dim Firstname As String 
    Dim Lastname As String 
End Structure 

と制御...

Public Property MyReadListViewData() As Employee 
    Get 
     Dim myEmployee As Employee 
     myEmployee.Lastname = ListView1.SelectedItems(0).Text 
     Return myEmployee 
    End Get 
    Set(ByVal value As Employee) 
     Me.ListView1.SelectedItems(0).Text = value.Lastname 
    End Set 
End Property 

典型的なVB6コード:

Private Sub Command4_Click() 
    Dim myEmployee As Employee 
    myEmployee = MyToolStrip1.MyReadListViewData 
    Text3.Text = myEmployee.Lastname 
End Sub 
+1

あなたはそれを使用可能にする構造定義に属性を適用する必要があります。あるいは、構造ではなくクラスを試してみましたか? – MarkJ

+1

構造体はCOMの問題です。非常にコンパイラ/ハードウェアに依存したレイアウトです。 IRecordInfoインターフェイスではほとんどサポートされていません。通常、タイプライブラリで構造体を宣言する必要があります。注目すべき点は、公開UDTを扱うように頼まれたときにVB6ビルドシステムがかなりボルケーであることです。 Employeeを代わりに[ComVisible]インターフェース+クラスとして宣言するだけで、この種の問題を回避できます。 –

+0

これをデモするためのコードをいくつか用意してください。 – ForEachLoop

答えて

0

あなたを渡して考えがありますデータセットとしての「もの」やXMLシリアル化の使用?私はVB6に精通していませんが、これはうまくいくと思います。何かの間でカスタムのものを渡すためには、どちらもそのことを「認識」しなければなりません。

また、interopの周りにラッパーを作成して、コードの重複を避けるために参照を追加することもできます。私は確かに言うことはできませんが、私はへの道を知りませんあなたのものは2つの間で無差別にしてください。

+0

私の唯一の経験は.NETでのOffice interopsです。私が話題から離れて話しているなら、私に知らせてください。 =) – Yatrix

+0

その間に私は安価な回避策を使用しています。その中のすべての情報を含む文字列を返して、もう一方の端でSplitを使用して展開します。それは両方向で動作します。一時的なソリューションには悪くないが、私はむしろより堅牢な方法をとるだろう。 – ForEachLoop

0

VB6で「変数がVisual Basicでサポートされていないオートメーションの種類を使用しています」エラーを表示する理由は、タイプライブラリで作成されたレコードがVB6に準拠していないためです。私がtrueにCOM可視セットを使って、新しいVB2005プロジェクトを作成:

Public Class Boing 

    Public Structure Employee 
     Dim FirstName As String 
     Dim LastName As String 
    End Structure 

    Public Sub GetEmployee(ByRef e As Employee) 

     e.FirstName = "Mark" 
     e.LastName = "Bertenshaw" 

    End Sub 

End Class 

私は、このDLLのタイプライブラリを作成するためにします。regasm/TLBを使用しました。

私はまた、テストVB6プロジェクト作成:私は正常にエラーをrepro'd

Private Sub Command_Click() 

    Dim udtEmployee As TestDotNetStructures.Employee 
    Dim oBoing As TestDotNetStructures.Boing 

    oBoing.GetEmployee udtEmployee 

End Sub 

を。

次に、(PowerVB Type Lib Editorを使用して)REGASMによって生成されたタイプライブラリを調べました。

Record Employee 
{ 
    LPWSTR FirstName 
    LPWSTR LastName 
} 

LPWSTRを含むレコードは、COMメソッドの引数としては無効です。 LPWSTRはCOM準拠型ではありません。一方、BSTRは間違いなくです。

修正がBSTRとして文字列を渡すためにVB.NETを伝えるためにマーシャリングは、あなたのVB.NETコードに属性を追加することです:

Imports System.Runtime.InteropServices 

<Microsoft.VisualBasic.ComClass()> Public Class Boing 

    Public Structure Employee 
     <MarshalAs(UnmanagedType.BStr)> Dim FirstName As String 
     <MarshalAs(UnmanagedType.BStr)> Dim LastName As String 
    End Structure 

    Public Sub GetEmployee(ByRef e As Employee) 

     e.FirstName = "Mark" 
     e.LastName = "Bertenshaw" 

    End Sub 

End Class 
関連する問題