- PR -

VB6製DLLの ByRef String 引数を持つメソッドを呼び出す方法

1
投稿者投稿内容
ダッチ
大ベテラン
会議室デビュー日: 2005/10/31
投稿数: 113
投稿日時: 2006-10-02 10:31
<環境>
OS:Windosw XP
言語:VB2003
アプリケーション:Windows アプリケーション

<問題点>
VB2003 で作成したアプリから
VB6 で作成した ActiveX DLL のメソッドを呼ぶことは出来るのですが、
ByRef String の引数に値が返ってきません。
呼び出す際に遅延バインディングで呼び出す必要があるため
VB6 DLL を参照設定できません。

<質問>
どのような呼び出し方をすると ByRef String に値が返ってくるのでしょうか。

<VB6DLLのソース>
コード:
Public Function ByRefMethod(ByRef str As String) As Integer
    str = "バイレフ"
End Function



<VB2003からの呼び出し>
コード:
Dim t As Type = Type.GetTypeFromProgID("VB6.Class1")

Dim o As Object = Nothing
Try
    o = Activator.CreateInstance(t)
    Dim objs() As Object = {""}
    Dim ret As Integer = CType(t.InvokeMember("ByRefMethod", BindingFlags.InvokeMethod, Nothing, o, objs), Integer)
    Console.WriteLine("ByRef引数 = {0}", objs(0)) ←値が入っていません。
Finally
    If Not o Is Nothing Then
        System.Runtime.InteropServices.Marshal.ReleaseComObject(o)
    End If
End Try


出力:ByRef引数 =

よろしくお願いいたします。
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-10-02 10:50
MSDN のヘルプを見ると System.String は不変であることがわかると思います。
http://msdn2.microsoft.com/ja-jp/library/system.string.aspx

引用:

String オブジェクトは、作成時点以降に値を変更できないことから、不変 (読み取り専用) と呼ばれます。String オブジェクトを変更するように見えるメソッドは、実際には変更内容が反映された新しい String オブジェクトを返します。文字列として使用されるオブジェクトの実際の内容を変更する必要がある場合には、System.Text.StringBuilder クラスを使用してください。


内容を変更する必要がある場合は、
ヘルプに書かれている通り、 System.Text StringBuilder を使ってください。
ダッチ
大ベテラン
会議室デビュー日: 2005/10/31
投稿数: 113
投稿日時: 2006-10-02 13:18
回答ありがとうございます。

引用:

かるあさんの書き込み (2006-10-02 10:50) より:
MSDN のヘルプを見ると System.String は不変であることがわかると思います。
http://msdn2.microsoft.com/ja-jp/library/system.string.aspx

引用:

String オブジェクトは、作成時点以降に値を変更できないことから、不変 (読み取り専用) と呼ばれます。String オブジェクトを変更するように見えるメソッドは、実際には変更内容が反映された新しい String オブジェクトを返します。文字列として使用されるオブジェクトの実際の内容を変更する必要がある場合には、System.Text.StringBuilder クラスを使用してください。


内容を変更する必要がある場合は、
ヘルプに書かれている通り、 System.Text StringBuilder を使ってください。



System.Text.StringBuilder を使用してみましたが、
例外が発生しました。
例外---------------------
'System.Reflection.TargetInvocationException' のハンドルされていない例外が mscorlib.dll で発生しました。

追加情報 : 呼び出しのターゲットが例外をスローしました。
-------------------------

修正したコードです。
コード:
Dim t As Type = Type.GetTypeFromProgID("VB6.Class1")

Dim o As Object = Nothing
Try
    o = Activator.CreateInstance(t)
    Dim sb As New StringBuilder
    Dim objs() As Object = {sb}
    Dim ret As Integer = CType(t.InvokeMember("ByRefMethod", BindingFlags.InvokeMethod, Nothing, o, objs), Integer)
    Console.WriteLine("ByRef引数 = {0}", objs(0))
Finally
    If Not o Is Nothing Then
        System.Runtime.InteropServices.Marshal.ReleaseComObject(o)
    End If
End Try


引数として渡す objs() に StringBuilder をいれてみました。

例外が発生した原因として
VB6 DLL の String の引数に StringBuilder を入れれなかったのが
原因と思われますが、どのようにして修正したらいいのかがわかりません。

そもそも ByRef String に対して結果が返ってくること自体出来るのかが
不安になってきました。

よろしくお願いいたします。
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2006-10-02 13:52
#これでいいのか不安だけど

ParameterModifier 構造体
http://msdn2.microsoft.com/ja-jp/library/system.reflection.parametermodifier.aspx
ダッチ
大ベテラン
会議室デビュー日: 2005/10/31
投稿数: 113
投稿日時: 2006-10-02 14:05
回答ありがとうございます。

引用:

まどかさんの書き込み (2006-10-02 13:52) より:
#これでいいのか不安だけど

ParameterModifier 構造体
http://msdn2.microsoft.com/ja-jp/library/system.reflection.parametermodifier.aspx



ズバリこれでした。

VB6 では String 型は値型でした。
.Net Freamework から String 型が参照型になりました。

この差をどのようにして埋めようかと悩んでいましたが、
まどかさんの指摘されたとおりに ParameterModifier を使用することで
解決することが出来ました。

最終的なコードはこのようになりました。
コード:

Dim t As Type = Type.GetTypeFromProgID("VB6.Class1")

Dim o As Object = Nothing
Try
o = Activator.CreateInstance(t)
Dim p As New ParameterModifier(1)
p(0) = True
Dim mods() As ParameterModifier = {p}
Dim objs() As Object = {""}
Dim ret As Integer = CType(t.InvokeMember("ByRefMethod", BindingFlags.InvokeMethod, Nothing, o, objs, mods, Nothing, Nothing), Integer)
Console.WriteLine("ByRef引数 = {0}", objs(0))
Finally
If Not o Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(o)
End If
End Try



出力:ByRef引数 = バイレフ

ありがとうございました。

[ メッセージ編集済み 編集者: ダッチ 編集日時 2006-10-02 14:07 ]

[ メッセージ編集済み 編集者: ダッチ 編集日時 2006-10-02 14:10 ]
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-10-02 17:19
うぁ、すでに終わっている。。。
まどかさん フォローありがとうございます。

ダッチさん、見当違いだったようで申し訳ないです。
ダッチ
大ベテラン
会議室デビュー日: 2005/10/31
投稿数: 113
投稿日時: 2006-10-02 17:34
引用:

かるあさんの書き込み (2006-10-02 17:19) より:

ダッチさん、見当違いだったようで申し訳ないです。


とんでもないです。
私だけでは解決できませんので。

少しでも情報が欲しいと思っていたなか、
回答していただいてありがとうございました。

硬くなっていた頭が少し柔らかくなった感じがします。

また、壁にぶちあったときにはよろしくお願いいたします。
1

スキルアップ/キャリアアップ(JOB@IT)