AG-TECH CORPAG-TECH CORP

ENGLISH

32ビット版Visual Basic
使用時におけるバイトアライメントの問題

ポジションブロックの問題とともに、Visual Basic (32bit) で BtrieveAPI を使用する場合にトラブルの原因となるのが、バイトアライメントの問題です。

バイトアライメント自体はVBに限らず他の言語でも行われていることですが、VB以外の言語ではコンパイル時のオプション指定などで、トラブルの発生を防ぐことができます。

 Visual Basic (32bit) の中でユーザ定義型(他の言語では構造体とかレコード型と呼ばれる)を使用すると、VBによってバイトアライメントが実行されます。

具体的には、ユーザ定義型の中で数値変数が使われていると、処理の最適化のために、数値変数が4バイトごとの境界にくるようVBが内部的に余分なバイトを挿入します。

Type DataBuffer

Field1(0 To 1) As Byte

Field2 As Long

Field3 As String * 10

End Type

これが内部的には、

Type DataBuffer

Field1(0 To 1) As Byte

Field2を4バイトの境界に動かすために、ここに余分な2バイトが挿入される

Field2 As Long

Field3 As String * 10

End Type

となってしまいます。

プログラマからこうしたことは見えませんが、VBの中だけで処理がすむのであれば、もちろん問題が表面化することはありません。

しかし、外部のDLLなどとデータの受け渡しを行う場合は、問題になってきます。

Btrieve アクセスの場合でいうと、データバッファをユーザ定義型で宣言し、BtrieveAPI を使ってレコードを読み込むとき、Btrieve は2バイト分広がった入れ物に対して、それとは知らずにデータを流し込んできます。

結果として、Field-1は正しく読み込めますが、Field-2は本来のデータである4バイト長整数の後ろ2バイト分とField-3の先頭2バイト分で構成され、Field-3には本来のデータから先頭2バイトを除いたデータが格納されているかのように見えてしまいます。

Btrieveはレコードの内容には一切手を加えません。それがどのような言語で書き込まれたものか、フィールドがどうなっているのか、どのようなデータ型であるのか、といったことには関知しません。単なるバイトの並びとして扱うだけです。データバッファに入っている通りをそのままファイルに書き出し、または読み出してアプリケーションに渡します。

 

 Visual Basic (32bit) におけるバイトアライメントの問題を解決するためには、Btrieveとのデータ受け渡しにバイト型配列を使うことです。

Type DataBuffer

Field1(0 To 1) As Byte

Field2 As Long

Field3 As String * 10

End Type

ではなく、

Type DataBuffer

Field1(0 To 1) As Byte

Field2(0 To 3) As Byte

Field3 As String * 10

End Type

このように定義します。

しかしこのままでは、Field-2をVB内で数値として扱えないので、バイト配列と数値変数間の変換処理が必要になります。VBにはメモリ間のコピー機能がないので、たとえばWindowsAPIを使って実現します。

 Declare Sub CopyMemory Lib “kernel32” Alias “RtlMoveMemory” ( _

  hpvDest As Any, _

  hpvSource As Any, _

  ByVal cbCopy As Long)

 Dim SampleDataBuffer As DataBuffer

 Dim lngField2Value As Long

 CopyMemory lngField2Value, SampleDataBuffer. Field2(0), 4

これでlngField2Valueが本来の長整数型の数値として扱えるようになります。

データを書き出す場合は、逆に、

 CopyMemory SampleDataBuffer. Field2(0), lngField2Value, 4

として、Btrieveに渡すデータバッファのバイト配列に正しくデータをセットします。

ユーザ定義型の中で数値変数(Integer,Long,Single,Double,Currencyなど)を使用する場合は、すべてこの処理が必要です。

また当然ですが、Get Equal などでキーバッファに数値をセットしなければならない時も、同様の処理が必要になります。

 



Contactお問い合わせ

お気軽にお問い合わせください。

お問い合わせ
必須会社名

個人のお客様は「個人」と入力してください。

必須お名前
必須メールアドレス
必須メールアドレス(確認)
必須ライセンス ありなし
ダウンロード目的