none
C#で作成したDllのVB.netからの呼び出しについての質問です。 RRS feed

  • 質問

  • たとえばC#のDllで以下の関数を作成します。

    public void TestA(int Value,Drawing.Color color)
    {
        //処理
    }

    public void TestA(int Value,ref Drawing.Color color)
    {
        //処理
    }

    同じC#から呼び出す分には
    それぞれ
    TestA(0, color);
    TestA(0, ref color);
    のように呼べますけど

    VB.netからだと
    class"クラス名"に同じ名前のメンバーが多種存在するためTestAがあいまいです。
    となり呼べませんが、C#のように明示的に呼ぶ方法はVB.netにはあるのでしょうか?

    それとも
    C#およびC++/CLIでDllを開発し、
    アプリケーション側の開発をVB.net
    として想定する場合、
    VB.net側での呼び出しかたも考慮してDllの組み方も変えなければならないのでしょうか?

    2014年12月4日 3:17

回答

  • VB.NetではByval,Byrefのオーバーロードできないです。
    そもそもオーバーロードでは継承関係で混乱することもあるので設計に注意が必要です。refも注意して設計するようにするだけですね。

    そういうオーバーロードがどういう場合で必要かわかりませんが、とりあえずVB.Netがわで

    Module Module1
    
        Sub Main()
            Dim c1 As New ClassLibrary1.Class1
            Dim col As System.Drawing.Color = New System.Drawing.Color
    
            c1.Class1TestA_Ref(1, col)
        End Sub
    
        <System.Runtime.CompilerServices.Extension()> _
        Sub Class1TestA_Ref(ByVal c1 As ClassLibrary1.Class1, ByVal i As Integer, ByRef color As System.Drawing.Color)
            Dim methods = c1.GetType().GetMethods().Where(Function(m)
                                                              Return m.Name = "TestA"
    
                                                          End Function)
            Dim mi As System.Reflection.MethodInfo
            For Each mi In methods
                Dim prms() As System.Reflection.ParameterInfo
                prms = mi.GetParameters()
                If (prms.Length = 2) Then
                    Dim prm As System.Reflection.ParameterInfo
                    prm = prms(1)
                    If (prm.ParameterType.Name = "Color&") Then
                        mi.Invoke(c1, New Object() {1, color})
                    End If
                End If
            Next
        End Sub
    End Module
    こんな、拡張メソッドをつくるとか。
    あるいは、新たにヘルパークラスを持つC#のDLLを作るとかで対応するしかないでしょうね。

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答の候補に設定 星 睦美 2014年12月4日 6:30
    • 回答としてマーク Crla 2014年12月4日 14:11
    2014年12月4日 4:05

すべての返信

  • VB.NetではByval,Byrefのオーバーロードできないです。
    そもそもオーバーロードでは継承関係で混乱することもあるので設計に注意が必要です。refも注意して設計するようにするだけですね。

    そういうオーバーロードがどういう場合で必要かわかりませんが、とりあえずVB.Netがわで

    Module Module1
    
        Sub Main()
            Dim c1 As New ClassLibrary1.Class1
            Dim col As System.Drawing.Color = New System.Drawing.Color
    
            c1.Class1TestA_Ref(1, col)
        End Sub
    
        <System.Runtime.CompilerServices.Extension()> _
        Sub Class1TestA_Ref(ByVal c1 As ClassLibrary1.Class1, ByVal i As Integer, ByRef color As System.Drawing.Color)
            Dim methods = c1.GetType().GetMethods().Where(Function(m)
                                                              Return m.Name = "TestA"
    
                                                          End Function)
            Dim mi As System.Reflection.MethodInfo
            For Each mi In methods
                Dim prms() As System.Reflection.ParameterInfo
                prms = mi.GetParameters()
                If (prms.Length = 2) Then
                    Dim prm As System.Reflection.ParameterInfo
                    prm = prms(1)
                    If (prm.ParameterType.Name = "Color&") Then
                        mi.Invoke(c1, New Object() {1, color})
                    End If
                End If
            Next
        End Sub
    End Module
    こんな、拡張メソッドをつくるとか。
    あるいは、新たにヘルパークラスを持つC#のDLLを作るとかで対応するしかないでしょうね。

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答の候補に設定 星 睦美 2014年12月4日 6:30
    • 回答としてマーク Crla 2014年12月4日 14:11
    2014年12月4日 4:05
  • はい、VBでそのようなメソッドを参照することはできません。

    今回の例は乗っていませんが、言語間の相互運用を考えるならこの辺りに一度目を通したほうがいいと思います。

    http://msdn.microsoft.com/ja-jp/library/730f1wy3(v=vs.90).aspx

    • 回答の候補に設定 星 睦美 2014年12月4日 6:30
    2014年12月4日 4:12
  • ご回答ありがとうございます^^

    やはりVB側からではそこがサポートされていないのですね。

    引数の数、型が同じで、一部参照渡しかどうかが異なる場合のオーバーロードされた関数が存在するクラスの該当関数に対するヘルパークラスをC#で作るのが一番楽そうですね。

    自身が設計したライブラリはまずそんな設計にしないのですが、

    たとえばSharpDXのようにC#での利用を主に想定したライブラリではそのようなオーバーロードされた関数が存在します。

    普段C++/CLI、C#でDLLを作成し、VB.NETで開発するので自身が作成する際にもその点を気を付けようと思います^^

    2014年12月4日 5:49
  • ご回答ありがとうございます^^

    言語間の相互運用に関しての注意点を自分で考えてる際にこの質問の点に気付いたので

    どのように対処するのだろうと思い今回の質問をしました。

    参考URLを読ませていただきます^^

    2014年12月4日 5:51
  • 詳しくは、かるあさんが示されてるURLをよく見ていただくとして、このような問題あるコードを書かないようにするために。CLS準拠という仕組みがあります。

    [assembly: CLSCompliant(true)]

    のように属性を適用しておくことで、共通言語仕様に準拠しないコードに警告を出すことが出来ます。

    2014年12月4日 12:20