ActiveBasic 3.1
ポインタの扱いについて

※Win32API関数のパラメータ引渡し方法について

以前までは、ByRef(ポインタ参照)を指定することで、変数ポインタの受け渡しを行っていましたが、今後はポインタ変数型を用いたByVal(値参照)指定が主流になってきます。また、ByVal、ByRefを省略したときのデフォルト値はByValになりますので、ご注意下さい。

ただし、以下の2点だけ、ByRef指定を利用する場合があります。

それぞれのAPI関数のパラメータが、「ポインタ変数のByVal指定」、「ByRefのポインタ参照」のどちらにあてはまるかはすべてヘルプファイルに記載してあります。今後は、ProjectEditorのパラメータ ヒントの表示を改良する、ポインタ変数型と基本データ型のエラーチェックを行うなどの対策を行っていく予定です。

もともとBasic言語はポインタという概念が薄いようで、ポインタ操作のための機能は正式にサポートされていませんでした。そこで、ActiveBasic3.0では、ポインタ概念を重要視し、ポインタ操作のための機能の充実をはかります。以下に、ActiveBasic3.0で採用されるポインタ変数の型を、VisualC++のものと比較しながら紹介していきます。

ActiveBasic3.0VisualC++
VoidPtrvoid *
DoublePtrdouble *
SinglePtrfloat *
DWordPtrDWORD *
WordPtrWORD *
BytePtrchar *

C言語では、&aなど、変数名の前にアンパサンド(&)を記述するとその変数のアドレスを取得することができましたが、ActiveBasicではVarPtr変数を利用することで同じ動作をさせることができます。

また、指定するポインタに格納されている値を取得することも、以下の関数を利用することで可能になります。これらの関数はコンパイラに組み込まれているので、機能を実現するための必要最小限の機械語が生成され、C言語並みのプログラムサイズ、動作速度が期待できます。

ActiveBasic3.0VisualC++
VarPtr(DoubleData)&DoubleData
VarPtr(SingleData)&SingleData
VarPtr(DWordData)&DWordData
VarPtr(WordData)&WordData
VarPtr(ByteData)&ByteData
a = GetDouble(lpDouble)a = *lpDouble
a = GetSingle(lpFloat)a = *lpFloat
a = GetDWord(lpDWord)a = *lpDWord
a = GetWord(lpWord)a = *lpWord
a = GetByte(lpByte)a = *lpByte
SetDouble(lpDouble,a)*lpDouble = a
SetSingle(lpSingle,a)*lpSingle = a
SetDWord(lpDWord,a)*lpDWord = a
SetWord(lpWord,a)*lpWord = a
SetByte(lpByte,a)*lpByte = a

例えば、ポインタ変数を利用してこんなことができます。

Dim lpByte As BytePtr
Dim hHeap As DWord

hHeap = GetProcessHeap()

'100バイト分のメモリを確保
lpByte = HeapAlloc(hHeap, 0, 100)

lpByte(0) = 0
lstrcat(lpByte, "〜1行目に表示される文字列〜" + Chr$(10))
lstrcat(lpByte, "〜こっちは2行目〜")

'バッファの内容を表示
MessageBox(0, lpByte, "test", 0)

'メモリを解放
HeapFree(hHeap, 0, lpByte)

このように、C言語などでよく見かける文字列操作がBasic言語でもできるようになります。

次は、このプログラムを、Byte型配列とポインタ変数を利用して再現してみます。

Sub GetTextBuffer(ByVal lpByte As BytePtr)
    lpByte(0) = 0
    lstrcat(lpByte, "〜1行目に表示される文字列〜" + Chr$(10))
    lstrcat(lpByte, "〜こっちは2行目〜")
End Sub

Dim ByteArray(100) As Byte
GetTextBuffer(ByteArray)

'バッファの内容を表示
MessageBox(0, ByteArray, "test", 0)