Windowsの型定義情報
WindowsはC/C++言語の標準的な型をほぼ使用していません。
Windows開発でよく使う型の情報は以下のようになっています。
■8bit
typedef char CHAR; typedef char TCHAR, *PTCHAR; typedef char CCHAR; typedef char *PSZ; typedef unsigned char UINT8, *PUINT8; typedef unsigned char UCHAR; typedef unsigned char BYTE; typedef unsigned char *LPBYTE; typedef unsigned char *PBYTE; typedef unsigned char uint8_t
16bit、32bit以降は現在環境がないため、後日記載。
■便利(と思われる)マクロ
■■min()、max()は既に宣言済み
NOMINMAX宣言がない場合、以下のマクロが使用可能。
#ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif
■■WINDOWSの最大パス長は260まで
#define MAX_PATH 260
■■BOOL変数の実態はintである。
BOOL変数に設定するのは以下の2つ。
#define FALSE 0 #define TRUE 1
■■コードには影響しないが、可読性が上がるマクロ
void hogehoge( IN int input, OUT int& response, OPTIONAL OUT LPVOID lpvResult);
のように、引数の方向を(無害に)示すことができる。
#define IN #define OUT #define OPTIONAL
■■いまや、near far は無意味である。
#define far #define near
https://docs.microsoft.com/ja-jp/cpp/cpp/stdcall?view=vs-2019
Stdcall呼び出し規約は、Win32 API 関数を呼び出すために使用されます。
呼び出し先がスタックを消去するので、コンパイラによって vararg 関数が cdeclされます。
この呼び出し規則を使用する関数には、関数プロトタイプが必要です。
__Stdcall修飾子は Microsoft 固有です。
#define CALLBACK __stdcall #define WINAPI __stdcall #define APIENTRY WINAPI #define APIPRIVATE __stdcall #define PASCAL __stdcall
https://docs.microsoft.com/ja-jp/cpp/cpp/stdcall?view=vs-2019
cdeclは、C および C++ プログラムの既定の呼び出し規約です。
スタックは呼び出し元によってクリーンアップされるため、機能をvararg実行できます。
cdecl呼び出し規約では、各関数呼び出しにスタック クリーンアップ コードを含める必要があるため、
stdcallよりも大きな実行可能ファイルが作成されます。 次の一覧は、この呼び出し規約の実装例を示しています。
cdecl修飾子は、マイクロソフト固有です。
#define WINAPIV __cdecl
検索しても、ほとんど見つからない。
□検索条件 "WINAPIV" 検索対象 *.* フォルダ C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0 除外ファイル *.msi;*.exe;*.obj;*.pdb;*.ilk;*.res;*.pch;*.iobj;*.ipdb 除外フォルダ .git;.svn;.vs (サブフォルダも検索) (英大文字小文字を区別する) (正規表現:bregonig.dll Ver.4.20 with Onigmo 6.2.0) (文字コードセットの自動判別) (一致した行を出力) C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared\minwindef.h(118,9) [UTF-8]: #define WINAPIV CDECL C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared\minwindef.h(129,9) [UTF-8]: #define WINAPIV __cdecl C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared\minwindef.h(136,9) [UTF-8]: #define WINAPIV C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um\celib.h(172,5) [UTF-8]: int WINAPIV ceDbgPrintf(BOOL fDebug, char const *pszfmt, ...); C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um\t2embapi.h(139,24) [UTF-8]: typedef unsigned long( WINAPIV *READEMBEDPROC ) ( void*, void*, const unsigned long ); C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um\t2embapi.h(140,24) [UTF-8]: typedef unsigned long( WINAPIV *WRITEEMBEDPROC ) ( void*, const void*, const unsigned long ); C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um\Vfw.h(59,17) [UTF-8]: #define VFWAPIV WINAPIV C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um\WinUser.h(325,1) [UTF-8]: WINAPIV C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um\WinUser.h(332,1) [UTF-8]: WINAPIV 9 個が検索されました。
■■ビット操作マクロ
BYTE変数2つからWORD変数を作ったり、WORD変数2つからLONG変数を作ったりするときに使用する。逆のLONGから上半分、下半分を抽出するマクロもある。
Windowsのメッセージ系API(PostMessageやGetMessage、SendMessageなど)で活用していた。 今、この関数を使う人は少ないと思われる。
#define MAKEWORD(a, b) ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8)) #define MAKELONG(a, b) ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16)) #define LOWORD(l) ((WORD)(((DWORD_PTR)(l)) & 0xffff)) #define HIWORD(l) ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff)) #define LOBYTE(w) ((BYTE)(((DWORD_PTR)(w)) & 0xff)) #define HIBYTE(w) ((BYTE)((((DWORD_PTR)(w)) >> 8) & 0xff))
■■各変数の最小値、最大値は既に宣言されている。
流石に、32Bitまで。
#define MINCHAR 0x80 #define MAXCHAR 0x7f #define MINSHORT 0x8000 #define MAXSHORT 0x7fff #define MINLONG 0x80000000 #define MAXLONG 0x7fffffff #define MAXBYTE 0xff #define MAXWORD 0xffff #define MAXDWORD 0xffffffff
■■64Bit変数は、__int64がプリミティブ宣言
大半はtypedefされたものを使用する。
typedef unsigned __int64 size_t; typedef __int64 LONGLONG; typedef unsigned __int64 ULONGLONG;
■■64bit化させるための構造体もある
WIN32APIとしては、こちらが、多用される。
例えば、QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCounter)など。
演算は.QuadPartでまとめたものを使います。数値が小さいはずだからと、LowPartだけで演算しようとすると、痛い目に遭います。
typedef union _LARGE_INTEGER { struct { DWORD LowPart; LONG HighPart; } DUMMYSTRUCTNAME; struct { DWORD LowPart; LONG HighPart; } u; LONGLONG QuadPart; } LARGE_INTEGER; typedef LARGE_INTEGER *PLARGE_INTEGER; typedef union _ULARGE_INTEGER { struct { DWORD LowPart; DWORD HighPart; } DUMMYSTRUCTNAME; struct { DWORD LowPart; DWORD HighPart; } u; ULONGLONG QuadPart; } ULARGE_INTEGER; typedef ULARGE_INTEGER *PULARGE_INTEGER;