我有一个名为" 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:\Query\Query\main.obj Query
Error 2 error LNK2005: "struct HWND__ * hwnd_Color_btn" (?hwnd_Color_btn@@3PAUHWND__@@A) already defined in controls.obj D:\Query\Query\main.obj Query
我根本没有看到问题。我承认,我对编程缺乏经验,但Visual Studio的搜索功能显示这些仅用于header和controls.cpp文件。
你能帮我跟踪一下这个问题吗?
答案 0 :(得分:2)
要在头文件中声明全局变量,您需要在其前面添加extern
。然后,您需要在单个源文件(而不是头文件)中定义变量的值。
在controls.h
:
extern HWND hwnd_Font_btn;
在controls.cpp
:
HWND hwnd_Font_btn;
如果省略头文件中的extern
,则在每个源文件中定义包含头文件的变量,并且不允许定义多个具有相同名称的变量。
你也可以这样想:
使用extern
声明变量告诉链接器,目标文件中的其他位置将有一个具有声明的类型和名称的变量。
不使用extern
实际上定义了包含初始值的变量,允许链接器引用与变量关联的内存位置。
答案 1 :(得分:0)
该行的每个实例:
#include "controls.h"
“粘贴”代码中该位置的“controls.h”。
这使得标题中的这些行......
HWND hwnd_Font_btn;
HWND hwnd_Color_btn;
...违反了One Definition Rule。
将它们更改为:
extern HWND hwnd_Font_btn;
extern HWND hwnd_Color_btn;
然后在一个cpp文件中定义一次。