データ型について

Win32 APIを使うとなると、どうしてもHSPでは使われないようなC言語の知識が必要になる部分が出てきてしまいます。この『データ型(data type)』もそういったものの1つです。

データ型とは、データの性格や数値の表現範囲などを規定するためのものです。すなわち、データのサイズや符号の有無、データが変更されるものかどうかを規定します。HSPでは符号付き32ビット整数と文字列の2種類だけですが、C言語では多くの型が存在します。

まず、Cの世界では最も基本的な型として以下のものがあります。(32ビット処理系の場合)

データ型 ビット幅 呼称 範囲
文字型 char 8 文字型 -128127
unsigned char 8 符号なし文字型 0255
整数型 short (int) 16 符号付き短長整数型 -3276832767
unsigned short (int) 16 符号なし短長整数型 065535
int 32 符号付き(倍長)整数型 -21474836482147483647
long (int)
unsigned (int) 32 符号なし(倍長)整数型 04294967295
unsigned long (int)
浮動小数点数型 float 32 単精度実数型 およそ10-381038(有効数字7桁)
double 64 倍精度実数型 およそ10-30810308(有効数字15桁)
型なし void - - -

データ型の中で ( ) で括った部分は省略可能です。

int型やunsigned int型のデータサイズは、16ビット環境では16ビット(2バイト)ですが、32ビット環境では32ビット(4バイト)になります。


さらに、上で示した基本データ型にアスタリスク("*")をつけたものは、そのデータ型へのポインタ(メモリアドレスを格納する変数)を表します。たとえば、「unsigned int*」は「unsignd int」型データへのポインタ、すなわち、「unsignd int」型の変数のアドレスを格納する変数の型を表しています。

また、データ型の先頭に「const」をつけると、それはデータの内容が変更されないことを示します。


さて、Win32 APIを使うプログラミングではこう言ったデータ型に別名をつけて、いろいろなデータの種類をわかりやすく表すようにしています。たとえば、「unsigned short int」に「WORD」という別名をつけて、それを1つの型として扱っています。他にも、「char*」を「LPSTR」としたりしています。以下にWin32 APIで使われる代表的なデータ型の一部を挙げておきます。

データ型 意味
BOOL TRUE1と定義)またはFALSE0と定義)のブール値。通常はFALSEであるかFALSE以外であるかで識別する。
BOOLEAN TRUE1と定義)またはFALSE0と定義)のブール値。通常はFALSEであるかFALSE以外であるかで識別する。(1バイト)
BYTE 8ビット符号なし整数(unsigned char型/1バイト)
CHAR 文字型(char型/1バイト)
COLORREF カラー値
DWORD 32ビット符号なし整数(unsigned long型 )
HWND ウィンドウハンドル
HDC デバイスコンテキストハンドル
HICON アイコンハンドル
HANDLE オブジェクトハンドル
HBITMAP ビットマップハンドル
HBRUSH ブラシハンドル
HCURSOR カーソルハンドル
HGDIOBJ GDIオブジェクトハンドル
HGLOBAL グローバルオブジェクトハンドル
HIMAGELIST イメージリストハンドル
HINSTANCE インスタンスハンドル
HMENU メニューハンドル
INT 符号付き整数(int型)
LANGID 言語ID(WORD型/2バイト)
LCID ロケールID(DWORD型/4バイト)
LONG 32ビット符号付き整数(long型)
LONGLONG 64ビット符号付き整数(__int64型/8バイト)
LPARAM 32ビットメッセージパラメータ
LPBOOL/PBOOL BOOL型へのポインタ
LPBYTE/PBYTE BYTE型へのポインタ
LPCSTR/PCSTR 定数ANSI(またはマルチバイト)文字列へのポインタ。(内容が変更されない)
LPCTSTR/PCTSTR ANSI版では定数ANSI(またはマルチバイト)文字列へのポインタ。Unicode版では定数ワイド文字列(Unicode文字列)へのポインタ。(内容が変更されない)
LPCVOID あらゆる型のデータへのポインタ。(内容が変更されない)
LPCWSTR/PCWSTR 定数ワイド文字列(Unicode文字列)へのポインタ。(内容が変更されない)
LPDWORD/PDWORD DWORD型へのポインタ
LPHANDLE/PHANDLE HANDLE型へのポインタ
LPINT/PINT INT型へのポインタ
LPLONG/PLONG LONG型へのポインタ
LPSTR/PSTR ANSI(またはマルチバイト)文字列へのポインタ
LPTSTR/PTSTR ANSI版ではANSI(またはマルチバイト)文字列へのポインタ。 Unicode版ではワイド文字列(Unicode文字列)へのポインタ。
LPVOID/PVOID あらゆる型のデータへのポインタ
LPWORD/PWORD WORD型へのポインタ
LPWSTR/PWSTR ワイド文字列(Unicode文字列)へのポインタ
PBOOLEAN BOOLEAN型へのポインタ
SHORT 16ビット符号付き整数(short型/2バイト)
TCHAR ANSI版ではCHAR型(1バイト)。Unicode版ではWCHAR型(2バイト)。
UINT 符号なし整数(unsigned int型)
ULONG 32ビット符号なし整数(unsigned long型)
ULONGLONG 64ビット符号なし整数(unsigned __int64型/8バイト)
VOID 型なし(void型)。
WCHAR 16ビットワイド文字(Unicode文字)(2バイト)
WORD 16ビット符号なし整数(unsigned short型/2バイト)
WPARAM 32ビットメッセージパラメータ

さて、HSPでWin32 APIを扱う場合には、データ型そのものは実はあまり問題になりません。問題となるのは、その型の表すデータのサイズなのです。たとえばCHAR型は8ビット(1バイト)であるとか、WORD型は16ビット(2バイト)であるといったことです。上の表で示したデータ型のデータサイズは、明示しているもの以外はすべて32ビット(4バイト)になります。Windowsは32ビット環境であるために、すべてのオブジェクトのハンドルは32ビット(4バイト)の大きさになりますし、ポインタに関しても、すべて32ビット仮想アドレスで表されているのでどのポインタも32ビット(4バイト)の大きさになります。

で、なぜこれらのサイズが問題になるのかというと、たとえばWORD型データ(サイズ2バイト)の配列をHSPで扱う場合を考えてみましょう。HSPの数値変数のサイズは4バイトであるために、スクリプト中で普通に

a = 100, 222, 314, 5413, ……

というように代入したのではWORD型の配列としては

100, 0, 222, 0, 314, 0, 5413, 0, ……

というようになってしまうのです。これでは期待したとおりの結果が得られなくなってしまうでしょう。WORD型の配列で

100, 222, 314, 5413, ……

とするためには、

a.0 = 100 + (222  << 16)     ; "+"を"|"にしてもよい
a.1 = 314 + (5413 << 16)

としなくてはならないのです。そのデータ型のデータサイズがいくらかを知ることがHSPでAPIを使っていく上では非常に重要になってきます。