c语言 - 如何避免全局常量出现"multiple definition"错误?



我正在用Windows API写一个C程序。每个主要函数都有自己的文件,并且有一个头文件用于原型和包含等等:

// Headers & global constants
#pragma once
#define _WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <WindowsX.h>
#include <Windef.h>
#define szClassName TEXT("EthicsPresentationWnd")
// Prototypes
LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK FontProc1(HWND hWnd, LPARAM lParam);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);
ATOM RegisterWindow(HINSTANCE hInstance);

让我恼火的是#define szClassName线。我不喜欢使用宏,更喜欢有一个适当的全局变量,wchar_t szClassName[],但如果我这样做,那么链接器抱怨在包含头的每个模块中都有多个定义的变量。

我以为#pragma once指令会阻止这一点,但它没有。

这个问题有解决办法吗?

解决这个问题的方法是有一个单独的声明和定义…

头(* . h;对不起,我不知道WinAPI类型名称,根据需要调整):

extern const char szClassName[];

实现(*.c或*.cpp)

const char szClassName[] = "hello, world"

你看到的问题,因为一个新的符号szClassName正在被声明,每次你的*.c或*.cpp文件之一包括头(即使与包括警卫!);这让链接器感到困惑(见下文)。

请注意,这将使sizeof(szClassName)不再工作。

<标题>进一步解释:

预处理后,编译器基本上看到如下:

  • file "a.c": const char someSymbol[] = <some text, don't care what right now>;
  • file "b.c": const char someSymbol[] = <some text, don't care if it's the same>;
  • file "c.c": const char someSymbol[] = <some text, ditto>;

当链接器正在链接对象文件时(例如,"a.obj", "b.obj"one_answers"c.obj"),它会看到相同的符号被定义为一个新值(至少就链接器而言)——因此它会失败,并出现错误。

放置在

#ifndef GLOB_CONST_H
#define GLOB_CONST_H 
// All macro definitions
// and type definitions
#endif   

使用extern关键字来声明全局变量,并将这些声明放在这个头文件中。之后,您需要将所有变量的定义放入.c文件中。

您可以将变量声明为static,以便包含.h文件的每个模块获得自己的本地唯一副本,链接器不会抱怨,因为每个副本将具有本地链接而不是外部链接。这也消除了将变量声明为extern并在单独的.c文件中定义它的需要。

static const TCHAR szClassName[] = TEXT("EthicsPresentationWnd");

或;

static const TCHAR *szClassName = TEXT("EthicsPresentationWnd");

或:

static LPCTSTR szClassName = TEXT("EthicsPresentationWnd");

在所有头文件中使用头保护,并在.c文件中声明一个全局变量,并在头文件中声明该全局变量的extern

#ifndef HEADER_FILE_NAME_H    /* if not defined already */
#define HEADER_FILE_NAME_H
extern wchar_t szClassName[];
#endif

在任何一个。c文件中定义全局变量

wchar_t szClassName[];

相关内容

  • 没有找到相关文章

最新更新