9

このマクロの意味がわかりません:

#define DECLARE_HANDLE(n) typedef struct n##__{int i;}*n

DECLARE_HANDLE(HWND);

私はCプログラムから次のことを学びました。

「##」はパラメータを接続することを意味します。

したがって、マクロは次のようになります。

typedef struct HWND__{int i;}*HWND

これは正しいですか?

もしそれが正しいなら、その文の意味は何ですか?

==================

ゲーム Bombermaaan のコード (Windows および Linux 用)、
リンクhttp://sourceforge.net/p/bombermaaan/code/HEAD/tree/trunk/src/Bombermaaan/winreplace.h
90 行目。

4

5 に答える 5

11

この構造の主な目的は、ハンドルの誤用を防ぐことです。すべてのハンドルが単にvoid *またはintまたはlong longその他の基本型である場合、別の代わりにいずれかを使用することを妨げるものは何もありません。へのポインターとへのstruct HWND__ポインターstruct HBITMAP__は同じものではないため、次のコードがある場合:

HWND hwnd;
HBITMAP hbmp;

hbmp = GetBitmap(...);
hwnd = hbmp;    // gives compiler error. 

API サプライヤーが真の宣言を提供したくないものに対して、一意の型を確実に取得することは、かなり古典的な手法です。適切な構造体宣言が必要な理由は完全にはわかりませんが、おそらく次の方法で問題を解決できます。

#define DECLARE_HANDLE(n) struct n ## __; struct n ## __ *n;

これにより、コンパイラが「不完全な型の使用」に反対するため、HWND の逆参照が不可能になることも保証されます。

于 2013-05-21T12:27:20.733 に答える
1

DECLARE_HANDLE(HWND);実際に展開します

typedef struct HWND__{int i;}*HWND;

さて、あなたはそれが何を意味するのか尋ねていますか?typedef を 2 つのステップに分割するだけです。

struct HWND__
{
    int i;
};

typedef HWND__* HWND;  // C++ only; for both C++ and C: typedef struct HWND__* HWND;

したがって、 (named )HWND__を含む構造体を定義し、型エイリアスをへのポインターとして宣言します。intiHWNDHWND__

于 2013-05-21T12:27:16.727 に答える
1

丁度。

これは、未知の構造体への不透明なポインターを宣言するために使用されます。

なぜ彼らがそれを単純に宣言しなかったのか私にはわかりません

typedef void* HWND;

構造体は整列できますが、基本型は整列できないため、おそらく整列の問題が原因です。
前述のように、型を構造体として宣言すると、コンパイル時の型チェックが可能になります。
頭がいい!

于 2013-05-21T11:51:32.770 に答える
0

を含むHWNDへのポインタとして a を定義します。struct HWND__int i

これで、コードで type を使用できるようになりましたHWND

于 2013-05-21T11:50:55.900 に答える