为什么链接器在c++中找不到这个本地定义

问题描述 投票:0回答:1

我有这个代码:

// Include guiddef.h
#include <guiddef.h>

// Define GUID 
DEFINE_GUID(MyGuid,
    0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0);

int main() {

    // Initialize variable with defined GUID
    GUID guid = MyGuid;

    // Can also directly use MyGuid

    return 0;
}

当我使用 VS 2022, 17.6.5 编译它时,我收到此链接器错误:

Error   LNK2001 unresolved external symbol MyGuid   testApplication 1   

为什么我会收到此错误?

c++ visual-studio guid
1个回答
2
投票

DEFINE_GUID
使用了一种半丑陋的 hack,可以在 C 中工作,但不能在 C++ 中工作。

当您使用

DEFINE_GUID
时,它会在其生成的代码的开头添加一个
extern
。在 C 语言中,这是无害的——你最终会得到所谓的“暂定定义”。暂定定义是声明和定义之间的中间点。一方面,您可以有多个同名的临时定义,只要它们不冲突(例如尝试为其提供不同的类型)就可以了。但如果没有可见的非暂定定义,它也将充当定义。

C++ 中与此最接近的等效项是

inline
变量定义(也可以多次出现,只要它们不冲突,并且最终都解析为单个对象)。但是,就目前而言,宏扩展为在开头包含
extern
的内容,并且在 C++ 中这严格来说是一个声明,而不是定义,因此当/如果您尝试在 C++ 中使用它时,您不会在任何地方都有定义,链接失败。

参考

https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-and-exporting-new-guids

将 GUID 定义放在防止多重包含的语句之外不会导致驱动程序中出现 GUID 的多个实例,因为 DEFINE_GUID 将 GUID 定义为 EXTERN_C 变量。只要类型匹配,就允许 EXTERN 变量的多个声明。

© www.soinside.com 2019 - 2024. All rights reserved.