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 *intlong long或其他一些基本类型,那么没有什么可以阻止您使用一个而不是另一个。指向 a 的指针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 回答
6

你的假设是正确的。

您可以使用以下简单的测试代码进行检查。

DECLARE_HANDLE(HWND);
struct HWND__ s;
HWND p = (HWND) malloc(sizeof(struct HWND__));
s.i = 20;
p->i = 100;
cout << "i valueis " << s.i<<" and " << p->i <<endl;
于 2013-05-21T12:09:43.830 回答
1

确切地。

这用于声明指向您未知的结构的不透明指针。

我不知道他们为什么不简单地将其声明为

typedef void* HWND;

可能是为了对齐问题,因为结构可以对齐但不是基本类型
如上所述,将类型声明为结构允许进行一些编译时类型检查。
聪明的!

于 2013-05-21T11:51:32.770 回答
1

DECLARE_HANDLE(HWND);确实扩展到

typedef struct HWND__{int i;}*HWND;

现在,你问这意味着什么?只需将 typedef 拆分为两个步骤:

struct HWND__
{
    int i;
};

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

因此,它定义了一个HWND__包含int(named i) 的结构,并将类型别名声明HWND指向 的指针HWND__

于 2013-05-21T12:27:16.727 回答
0

它将 a 定义HWND为指向struct HWND__包含的指针int i

因此,现在您可以在代码中使用 type HWND

于 2013-05-21T11:50:55.900 回答