C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

VB6 シリアライズされたオブジェクトを VB.netで復元

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■102671 / inTopicNo.1)  VB6 シリアライズされたオブジェクトを VB.netで復元
  
□投稿者/ こじま まさと (1回)-(2023/12/05(Tue) 09:12:55)

分類:[ASP.NET (VB)] 

VB6
VB.net(ver4.8)

VB6でType宣言されたオブジェクトをシリアライズしたデータを
VB.netでデシリアライズしようとしています。

以下 テストで、

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

として、テストしてみましたが、デシリアライズができませんでした。

そもそも、
VB6でType内で配列で定義されている場合、VB.net側でデシリアライズ可能なのでしょうか?
可能であれば、どのようにソースをかけば良いのか、ご指導いただければと存じます。

拙い説明で申し訳ございませんが、お知恵をかりることができればと存じます。

よろしくお願い申し上げます。


引用返信 編集キー/
■102672 / inTopicNo.2)  Re[1]: VB6 シリアライズされたオブジェクトを VB.netで復元
□投稿者/ 魔界の仮面弁士 (3732回)-(2023/12/05(Tue) 10:24:24)
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)
引用返信 編集キー/
■102673 / inTopicNo.3)  Re[2]: VB6 シリアライズされたオブジェクトを VB.netで復元
□投稿者/ こじま まさと (2回)-(2023/12/05(Tue) 12:04:01)
魔界の仮面弁士 さん

お世話になっております。

確かに、vb側の
HP(1 To 8) As Single
の理解が不十分でした。

ご指摘の通り、プロパティを自作して対応して、
VB6でシリアライズされたオブジェクトを、
VB.Netでデシリアライズできました。

ご対応いただきありがとうございました。







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)
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ