none
構造体のByRefによる参照渡しについて RRS feed

  • 質問

  • プログラミングをしているときに途中で気がついたのですがどうしても解消法が分からないので投稿しました。

    本来はDLL(クラスライブラリ)とアプリケーションと分裂しているのでわかりやすいようソースを似たようなことを書きました。

     

    以下のソースコードを見てください

    フォームのロードイベントが本来の実行ファイルのコードで

    それ以下はすべてDLLに収納されているということでお願いします。

     

     

     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

      Dim a(0) As hito
      add(a(0))
      Start()
      MessageBox.Show(a(0).name)

     End Sub

     

     

     Public Structure hito
      Dim name As String
     End Structure

     

     Dim hairetu(0) As hito

     

     Public Sub add(ByRef a As hito)
      hairetu(0) = a
     End Sub

     

     Public Sub Start()
      method1()
     End Sub

     

     Public Sub method1()
      hairetu(0).name = "人だよ"
     End Sub

     

    このときイベントで宣言されたhito構造体配列が宣言されDLLに存在するaddメソッドの第一引数に

    a(0)の参照を渡しDLLにあるhairetu構造体配列のバッファに詰めておいて

    ある程度addが呼び出されたらstartメソッドを呼び出しバッファリングしてもらうという構造です。

    本来は指定されたファイルをADDしてもらいStartメソッドで一気に読み込んでもらう用にしたかったのですが

    これだとなぜかバッファリングされないようです。

    ByRefパラメータで宣言してるはずなのになぜか値が格納されません、構造体に限っては参照渡しは無理なのでしょうか?

    2007年8月30日 18:39

回答

  • 今のプログラムの流れを崩さないと言うことではClassに変えるのが一番楽かと思います。

    当方でのテストコードそのまま載せます。

     

    Code Snippet

      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim a(0) As hito
        a(0) = New hito
        add(a(0))
        Start()
        MessageBox.Show(a(0).name)
      End Sub

      Public Class hito
        Public name As String
      End Class

      Dim hairetu(0) As hito

      Public Sub add(ByVal a As hito)
        hairetu(0) = a
      End Sub

      Public Sub Start()
        method1()
      End Sub

      Public Sub method1()
        hairetu(0).name = "人だよ"
      End Sub

     

     

    2007年8月31日 5:59
  • Tondon さん、こんにちは。

    調べたいことがある時はまずリファレンスを見るか検索してみてください。

    いかがでしょうか?

    2007年8月31日 16:28

すべての返信

  • おはようございますTondonさん。

    ByRefはうまくいっていますが、addメソッドのhairetu(0) = aで構造体の中身がコピーされています。Tondonさんはここで構造体の参照がコピーされることを期待されていますが、そこが意図したとおりにならない理由です。Classの場合は参照がコピーされますので、いちいちNewしないといけないのが面倒になりますがClassにされると動作します。その場合はByValでも動作します。こちらではDLLに分けないでテストしましたがたぶんDLLでも動くと思います。

    2007年8月30日 23:19
  • こんにちは、三輪の牛さん、

    ご回答ありがとうございます。

     

    そうですか、参照がコピーされないで内容がコピーされるのですか・・・・・

    では、対処法としては構造体として定義しているのをクラスとして定義しなおすというのがベストでしょうか・・・?

    2007年8月31日 5:35
  • 今のプログラムの流れを崩さないと言うことではClassに変えるのが一番楽かと思います。

    当方でのテストコードそのまま載せます。

     

    Code Snippet

      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim a(0) As hito
        a(0) = New hito
        add(a(0))
        Start()
        MessageBox.Show(a(0).name)
      End Sub

      Public Class hito
        Public name As String
      End Class

      Dim hairetu(0) As hito

      Public Sub add(ByVal a As hito)
        hairetu(0) = a
      End Sub

      Public Sub Start()
        method1()
      End Sub

      Public Sub method1()
        hairetu(0).name = "人だよ"
      End Sub

     

     

    2007年8月31日 5:59
  • Tondonです。

     

    おぉーー!サンプルコードまで書いていただき本当にありがとうございます。

    心中からありがたく思います!

     

    あと、気になったんですが

    構造体とクラスはどのような場合に使い分けたらいいのでしょうか??

    あまりにも性質が似てて使う区別がなかなかつかなくて・・・・・・

    2007年8月31日 13:50
  • Tondon さん、こんにちは。

    調べたいことがある時はまずリファレンスを見るか検索してみてください。

    いかがでしょうか?

    2007年8月31日 16:28
  • じゃんぬねっとさんこんにちは

     

    すみません、つい駄文を書いてしまいました。

    今後注意します。

    あと、参考URLの提供もありがとうございます。

    2007年8月31日 16:34