VB6でswab関数と同じ事をする場合

解決


ののさん  2012-09-17 21:34:20  No: 103365  IP: [192.*.*.*]

VB6でVC6のswab関数と同じことをするにはどうすればよいでしょうか。
第一引数、第二引数には構造体を指定してswapさせたいのですが
byte配列ではなく、構造体をどうswapさせればよいのかが分かりません。
よろしくお願いします。

編集 削除
魔界の仮面弁士  2012-09-18 11:52:33  No: 103366  IP: [192.*.*.*]

> VB6でVC6のswab関数と同じことをするにはどうすればよいでしょうか。

そのものズバリの物は作れません。型を明示した上で
  Sub swab1_1(ByRef a As Type1, ByRef b As Type1)
  Sub swab1_2(ByRef a As Type1, ByRef b As Type2)
  Sub swab2_1(ByRef a As Type2, ByRef b As Type1)
  Sub swab2_2(ByRef a As Type2, ByRef b As Type2)
のようなものを作る事ならばできますけれどね。


一応「同じユーザー定義型同士」もしくは
「同じバイナリサイズのユーザー定義型同士」ならば、
LSet ステートメントを用いてデータをコピーできます。
(異なるサイズの場合、不足した部分のコピーは実施されません)

データ構造によっては、これで凌げないかを検討してみてください。

Option Explicit

Private Type A
    X As Byte
    Y As Byte
    Z As Integer
End Type

Private Type B
    L As Long
End Type

Private Type C
    V(0 To 3) As Byte
End Type

Private Sub Form_Load()
    Dim A1 As A
    Dim B1 As B
    Dim C1 As C

    A1.X = &H12
    A1.Y = &H34
    A1.Z = &H5678

    LSet B1 = A1
    LSet C1 = A1

    Debug.Print "A=";
    Debug.Print Right("00" & Hex(A1.X), 2);
    Debug.Print Right("00" & Hex(A1.Y), 2);
    Debug.Print Right("0000" & Hex(A1.Z), 4)

    Debug.Print "B=";
    Debug.Print Right("00000000" & Hex(B1.L), 8)

    Debug.Print "C=";
    Dim V As Variant
    For Each V In C1.V
        Debug.Print Right("00" & Hex(V), 2);
    Next
    Debug.Print
End Sub



いずれにせよ、結論としては
>> #include <string.h> 
>> void swab(const void *from, void *to, size_t n);
のようなことはできません。

そもそもVB ではユーザー定義型を受け取るための汎用型がありません。そのため
  Sub swab(ByRef a As Variant, ByRef b As Variant)
  Sub swab(ByRef a As Any, ByRef b As Any)
のようなプロシージャを用意することができないためです。

「ユーザー定義型」ではなく、レジストリ登録された構造体であれば、
Variant で受けることもできますけれどね。


> byte配列ではなく、構造体をどうswapさせればよいのかが分かりません。
上記以外では、RtlMoveMemory API 等を併用して、メモリコピーを行うぐらいでしょうか。
(あとは、バイナリファイルに Put# して Get# しなおすとか)

アライメント調整のパディングが含まれている場合や、参照型を含んだユーザー定義型では
単純コピーというわけにも行かないでしょうけれどね。

編集 削除
ののさん  2012-09-27 10:51:35  No: 103367  IP: [192.*.*.*]

返事が遅くなりまして申し訳ありません。

>そのものズバリの物は作れません。型を明示した上で
>  Sub swab1_1(ByRef a As Type1, ByRef b As Type1)
>  Sub swab1_2(ByRef a As Type1, ByRef b As Type2)
>  Sub swab2_1(ByRef a As Type2, ByRef b As Type1)
>  Sub swab2_2(ByRef a As Type2, ByRef b As Type2)
>のようなものを作る事ならばできますけれどね。

魔界の仮面弁士様にアドバイス頂いたように、
型固定+swapバイト数固定の関数を用途別に用意することにしました。
その関数は以下の①〜③内容で作成しています。

①作成した関数の中で構造体データを一度、バイト配列に格納
②バイト配列の奇数要素⇔偶数要素を入れ替え
③再度バイト配列から構造体データに移す

ありがとうございました!

編集 削除