神秘的多个声明

Mysterious multiple declarations

本文关键字:声明      更新时间:2023-10-16

我有一个名为"controls.h"的文件,它声明了将在 Win32 应用程序中使用的按钮的句柄。

#ifndef  CONTROLS_H
#define CONTROLS_H
#include "Window.h"
HWND hwnd_Font_btn;
HWND hwnd_Color_btn;
#pragma region UI_FUNCTION_DEC
bool DrawUI(HWND parenthwnd);
#pragma endregion
#endif

这些句柄和函数声明在名为"controls.cpp"的文件中使用

#include "controls.h"
bool DrawUI(HWND parenthwnd)
{
    hwnd_Font_btn = CreateWindowEx(NULL, L"BUTTON", L"Select Font", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 
        10, 10, 100, 25, parenthwnd, NULL, (HINSTANCE)GetWindowLong(parenthwnd, GWL_HINSTANCE), NULL);
    hwnd_Color_btn = CreateWindowEx(NULL, L"BUTTON", L"Select Color", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
        10, 45, 100, 25, parenthwnd, NULL, (HINSTANCE)GetWindowLong(parenthwnd, GWL_HINSTANCE), NULL);
    return true;
}

然后将"Controls.h"包含在"main.cpp"中,然后调用DrawUI。但是,我无法编译代码,因为 Visual Studio 说句柄是在多个位置声明的。

Error   1   error LNK2005: "struct HWND__ * hwnd_Font_btn" (?hwnd_Font_btn@@3PAUHWND__@@A) already defined in controls.obj  D:QueryQuerymain.obj Query
Error   2   error LNK2005: "struct HWND__ * hwnd_Color_btn" (?hwnd_Color_btn@@3PAUHWND__@@A) already defined in controls.obj    D:QueryQuerymain.obj Query

我根本看不出问题所在。我承认,我在编程方面没有经验,但Visual Studio的搜索功能显示这些仅用于标题和控件.cpp文件。

你能帮我追踪问题吗?

要在头文件中声明全局变量,您需要在它前面加上 extern 。然后,您需要在单个源文件(不是头文件)中定义变量的值。

controls.h

extern HWND hwnd_Font_btn;

controls.cpp

HWND hwnd_Font_btn;

省略头文件中的extern时,可以在包含头文件的每个源文件中定义变量,并且不允许定义多个同名变量。

你也可以这样想:

使用 extern 声明变量会告诉链接器,对象文件中的其他位置将有一个具有声明类型和名称的变量。

不使用extern实际上定义了变量,包括允许链接器引用与变量关联的内存位置的初始值。

该行的每个实例:

#include "controls.h"

整个"controls.h"粘贴"到代码中的该位置。

这使得该标题中的这些行...

HWND hwnd_Font_btn;
HWND hwnd_Color_btn;

。违反一个定义规则。

将它们更改为:

extern HWND hwnd_Font_btn;
extern HWND hwnd_Color_btn;

然后在一个 cpp 文件中定义它们一次