DOBON.NET DOBON.NETプログラミング掲示板過去ログ

要素が構造体配列である構造体のサイズ取得について

環境/言語:[VB.NET]
分類:[.NET]

要素に構造体配列を持っている構造体のサイズを取得しようとして、以下のようにしました。
実行すると Len(sr2) で 0 が戻ってきます。(80 が戻ってきてほしかったのすが)。

要素が構造体配列の構造体のサイズを知るには(上記の例ですと 80 を取得するには)どのようにすればよろしいのでしょうか。

よろしくお願いいたします。
(環境:VB2005)


=======以下コード=======
'構造体の定義
Public Structure STR1
    Dim i1 As Integer
    Dim i2 As Integer
End Structure

Public Structure STR2
    <VBFixedArray(9)> Dim sr1() As STR1
    Public Sub Initialize()
        ReDim sr1(9)
    End Sub
End Structure

Public sr2 As STR2

'サイズ取得
sr2.Initialize()
Console.WriteLine("Len = " + Len(sr2).ToString)
2006/07/21(Fri) 11:22:30 編集(投稿者)

■No16758に返信(fpaさんの記事)
> 要素に構造体配列を持っている構造体のサイズを取得しようとして、以下のようにしました。
> 実行すると Len(sr2) で 0 が戻ってきます。(80 が戻ってきてほしかったのすが)。
> 要素が構造体配列の構造体のサイズを知るには(上記の例ですと 80 を取得するには)どのようにすればよろしいのでしょうか。
80なんて返ってくるわけがないと思いますね。

> Console.WriteLine("Len = " + Len(sr2).ToString)
Len関数って何を返すかわかられてます?

Console.WriteLine("Len = " + sr2.sr1.Length.ToString)
で配列の長さは返りますが、今回の例では10が返って来ます。
Imports System, System.Runtime.InteropServices
Module Module1
    <StructLayout(LayoutKind.Sequential, Pack:=1)> _
    Public Structure STR1
        Dim i1 As Integer
        Dim i2 As Integer
    End Structure

    <StructLayout(LayoutKind.Sequential, Pack:=1)> _
    Public Structure STR2
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=10)> _
        Dim sr1() As STR1
        Public Sub Initialize()
            ReDim sr1(9)
        End Sub
    End Structure

    Public sr2 As STR2

    Sub Main()
        sr2.Initialize()

        'Size=80
        Console.WriteLine("Size={0}", Marshal.SizeOf(sr2))

        Console.WriteLine("Enter を押してください:")
        Console.ReadLine()
    End Sub
End Module
■No16761に返信(魔界の仮面弁士さんの記事)
> 'Size=80
> Console.WriteLine("Size={0}", Marshal.SizeOf(sr2))

.NET で「構造体のサイズ」というと,
(1) アンマネージドな世界へマーシャリング後のサイズ及びメモリレイアウト
(2) マネージドな世界での(Unsafe コード等での),オリジナルのサイズ及びメモリレイアウト
の 2 種類がありますね.

まあ統計的に掲示板等での質問が多いのはやはり (1) の方で,回答も Marshal.SizeOf が提示されることは多いですが,C# の sizeof 演算子や,FieldOffset を指定したオブジェクトにマネージドな世界でアクセスする場合は (2) について考慮する必要があります.

興味がある方は,下記の sizeof 演算子の結果と,Marshal.SizeOf の結果が一致しない例を作ってみるとおもしろいかも.
http://www.atmarkit.co.jp/fdotnet/csharp_abc2/csabc2_021/cs2_021_03.html
ありがとうございました。サイズ取得できました。

下のようなプリミティブ型の配列の時は Len(sr2)のようにしてサイズを取得できたので、構造体配列の場合でも、Len関数でサイズが取れると考えてました。
このあたりの違いは調べていこうと思います。

Public Structure STR3
    <VBFixedArray(9)> Dim s1() As Short
    <VBFixedArray(9)> Dim i1() As Integer
    Public Sub Initialize()
        ReDim s1(9)
        ReDim i1(9)
    End Sub
End Structure
Public sr3 As STR3

ここでLen(sr3)とすると 60 がとれる。


あと、お聞きしてばかりですみませんが、もう1点構造体のサイズについて質問させてください。
以下のような構造体のサイズ取得はどのようにして記述すればよいのでしょうか。
(構造体配列と文字列の配列を要素に持っているような構造体)

Public Structure STR2
    <VBFixedArray(9)> Dim sr1() As STR1     '構造体の配列
    <VBFixedArray(9), VBFixedString(5)> Dim s() As String    '文字列の配列
    Public Sub Initialize()
        ReDim sr1(9)
        Redim s(9)
    End Sub
End Structure


■No16761に返信(魔界の仮面弁士さんの記事)
> Imports System, System.Runtime.InteropServices
> Module Module1
>     <StructLayout(LayoutKind.Sequential, Pack:=1)> _
>     Public Structure STR1
>         Dim i1 As Integer
>         Dim i2 As Integer
>     End Structure
           :
           :
>         Console.WriteLine("Size={0}", Marshal.SizeOf(sr2))
> 
>         Console.WriteLine("Enter を押してください:")
>         Console.ReadLine()
>     End Sub
> End Module

DOBON.NET | プログラミング道 | プログラミング掲示板