VB6側 Type Layout FileType As String Version As String Orientation As Integer End Type
VB.net側 Structure Layout Dim FileType As String Dim Version As String Dim Orientation As Short End Structure
は、デシリアライズ可能でしたが、
実際のプログラム内は VB6側 Type Layout FileType As String Version As String Orientation As Integer HP(1 To 8) As Single LV(0 To 15) As Integer End Type
と、配列を宣言されていました。
VB.net側で Structure Layout Dim FileType As String Dim Version As String Dim Orientation As Short Dim HP() As Single Dim LV() As Short End Structure Public Sub New ReDim HP(9) ReDim LV(16) End Sub
として、作成しましたが、デシリアライズされませんでした。
調査を行い、 Structure Layout Dim FileType As String Dim Version As String Dim Orientation As Short <VBFixedArray(9)> Dim HP() As Single <VBFixedArray(16)> Dim LV() As Short End Structure
や
Structure Layout Dim FileType As String Dim Version As String Dim Orientation As Short <MarshalAs(UnmanagedType.ByValArray, ArraySubType:=UnmanagedType.Struct, SizeConst:=9)> Dim HP() As Single <MarshalAs(UnmanagedType.ByValArray, ArraySubType:=UnmanagedType.Struct, SizeConst:=16)> Dim LV() As Short End Structure
元の HP は (1 To 8) As Single の 32 バイトなのに、 .NET 側では 36 バイトで宣言されていますし。
Option Base 1 をエミュレートしたいのであれば、プロパティを自作して対応しましょう。
<Serializable> Structure Layout Public FileType As String Public Version As String Public Orientation As Short <VBFixedArray(7)> Public _HP() As Single <VBFixedArray(15)> Public LV() As Short
Public Property HP(Index As Integer) As Single Get If Index < 1 OrElse 8 < Index Then Throw New IndexOutOfRangeException() Return _HP(Index - 1) End Get Set(value As Single) If Index < 1 OrElse 8 < Index Then Throw New IndexOutOfRangeException() _HP(Index - 1) = value End Set End Property
'Public Overrides Function ToString() As String ' Return $"FileType={FileType}, Version={Version}, Orientation={Orientation}, HP={{{String.Join(", ", Array.ConvertAll(_HP, AddressOf Convert.ToString))}}}, LV={{{String.Join(", ", Array.ConvertAll(LV, AddressOf Convert.ToString))}}}" 'End Function End Structure
Dim t As New Layout() Dim fno As Integer = FreeFile() FileOpen(fno, FileFullPath, OpenMode.Binary) Do Until EOF(fno) 'Option Strict Off の場合 ' 'FileGet(fno, t) '
'Option Strict On の場合 Dim w As ValueType = t FileGet(fno, w) t = DirectCast(w, Layout)
■No102672 (魔界の仮面弁士 さん) に返信 > ■No102671 (こじま まさと さん) に返信 >>デシリアライズができませんでした。 > .NET 側の構造体サイズが、VB6 側のユーザー定義型サイズと異なっていますよね? > > 元の HP は (1 To 8) As Single の 32 バイトなのに、 > .NET 側では 36 バイトで宣言されていますし。 > > Option Base 1 をエミュレートしたいのであれば、プロパティを自作して対応しましょう。 > > > > <Serializable> > Structure Layout > Public FileType As String > Public Version As String > Public Orientation As Short > <VBFixedArray(7)> Public _HP() As Single > <VBFixedArray(15)> Public LV() As Short > > Public Property HP(Index As Integer) As Single > Get > If Index < 1 OrElse 8 < Index Then Throw New IndexOutOfRangeException() > Return _HP(Index - 1) > End Get > Set(value As Single) > If Index < 1 OrElse 8 < Index Then Throw New IndexOutOfRangeException() > _HP(Index - 1) = value > End Set > End Property > > 'Public Overrides Function ToString() As String > ' Return $"FileType={FileType}, Version={Version}, Orientation={Orientation}, HP={{{String.Join(", ", Array.ConvertAll(_HP, AddressOf Convert.ToString))}}}, LV={{{String.Join(", ", Array.ConvertAll(LV, AddressOf Convert.ToString))}}}" > 'End Function > End Structure > > > > Dim t As New Layout() > Dim fno As Integer = FreeFile() > FileOpen(fno, FileFullPath, OpenMode.Binary) > Do Until EOF(fno) > 'Option Strict Off の場合 > ' > 'FileGet(fno, t) > ' > > 'Option Strict On の場合 > Dim w As ValueType = t > FileGet(fno, w) > t = DirectCast(w, Layout) > > 'Debug.WriteLine(t) > Loop > FileClose(fno)