教えて下さい。
VB2005の超初心者です…。
Structure INFO2
Dim a2 As Integer
End Structure
Structure INFO1
Dim a1 As Integer
Dim i2 As INFO2
End Structure
Dim i1 as INFO1
上のような構造体を宣言しました。
で、Len(i1)で構造体のサイズを取得しようとしたのですが
返ってきた答えは4…。
VB6ではちゃんと8が返ってきたはずなんです。
どのようにすればいいのでしょうか?
よろしくお願いします…。
> 返ってきた答えは4…。
> VB6ではちゃんと8が返ってきたはずなんです。
あれ? 当方の VB2005 では「8」が返されましたよ。
Public Class Form1
Structure INFO2
Dim a2 As Integer
End Structure
Structure INFO1
Dim a1 As Integer
Dim i2 As INFO2
End Structure
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
Dim i1 As INFO1
MsgBox(Len(i1))
End Sub
End Class
> どのようにすればいいのでしょうか?
Len 関数で良いと思いますが、他の方法ということであれば、
Marshal クラスの SizeOf メソッドでサイズを得られます。
ただし、(VB6 で、Len と LenB の結果が異なる場合があったように)
Len と Marshal.SizeOf とで、結果が異なることがある点にはご注意を。
もし、そうしたメンバ間のパディングの扱いまで考慮する必要が
あるのなら、StructLayoutAttribute 属性の併用を検討してみてください。
すいません。
自分が出した例ではちゃんとなりますね…。
Structure INFO2
Dim a2 As Integer
End Structure
Structure INFO1
Dim a1 As Integer
<VBFixedArray ( 3)> Dim i2() As INFO2
End Structure
Dim i1 as INFO1
です。
お手間かけましたがよろしくお願いします…。
> 自分が出した例ではちゃんとなりますね…。
で、新しい例の場合には、どのような値が欲しいのでしょうか?
また、それらの構造体を、どのように利用されるのでしょうか?
それによって、適切な対処方法も変わってくるかと。
> お手間かけましたがよろしくお願いします…。
先に回答した Marshal クラス等では、目的を果たせませんか?
Imports System.Runtime.InteropServices
Module Module1
Structure INFO1
Dim a As Integer
End Structure
Structure INFO2
Dim a As Integer
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Dim b() As INFO1
End Structure
Structure INFO3
Dim a As Integer
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Dim b() As Integer
End Structure
Sub Main()
Dim x As INFO2, y As INFO3
ReDim x.b(3), y.b(3)
Console.WriteLine("SizeOf(INFO2)=" & Marshal.SizeOf(x).ToString())
Console.WriteLine("SizeOf(INFO3)=" & Marshal.SizeOf(y).ToString())
Console.ReadLine()
End Sub
End Module
ありがとうございます!
教えていただいたコードにてテストすると、思った値が返ってきました。
で、ちょっと変更してやると…だめでした…。
Imports System.Runtime.InteropServices
Module Module1
Structure INFO1
Dim a As Integer
Dim b As Byte
End Structure
Structure INFO2
Dim a As Integer
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Dim b() As INFO1
End Structure
Structure INFO3
Dim a As Integer
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Dim b() As Integer
End Structure
Sub Main()
Dim x As INFO2, y As INFO3
ReDim x.b(3), y.b(3)
Console.WriteLine("SizeOf(INFO2)=" & Marshal.SizeOf(x).ToString())
Console.WriteLine("SizeOf(INFO3)=" & Marshal.SizeOf(y).ToString())
Console.ReadLine()
End Sub
End Module
実際には24が返ってくるはずなのですが、実際には36が返ってきてしまいます。
どうやらINFO1が8バイトとなってしまっているようです。
どのように利用するかというと、
ハードディスクにあと何件データが保存できるか求めたいのです。
ハードディスクの空き容量は取得できたので、あとデータ構造のサイズがわかれば
単純計算で求まるかなと…。
よろしくお願いします…。
> 実際には24が返ってくるはずなのですが、実際には36が返ってきてしまいます。
返ってくる「はず」という表現はどうかと思いますが。(^^;
VB6 で試した場合も、Len=24、LenB=36 ですよね。
で、その件については、すでに最初の回答で述べているように、
>>> もし、そうしたメンバ間のパディングの扱いまで考慮する必要が
>>> あるのなら、StructLayoutAttribute 属性の併用を検討してみてください。
ということです。すなわち、
<StructLayout(LayoutKind.Sequential, Pack:=1)> Structure INFO1
<StructLayout(LayoutKind.Sequential, Pack:=1)> Structure INFO2
のように属性を付加するということです。
> ハードディスクにあと何件データが保存できるか求めたいのです。
それは、シリアライズの方法に依存するのでは無いでしょうか?
XML 形式で保存した場合、BinaryFormatter で永続化した場合、
独自形式で保存した場合、さらにそれらを圧縮した場合などなど…。
できました!
長々と本当にありがとうございました!
本当に助かりました…。
ツイート | ![]() |