-1

I have this code:

// 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;
}

and when I compile it using VS 2022, 17.6.5, I am getting this linker error:

Error   LNK2001 unresolved external symbol MyGuid   testApplication 1   

Why I am getting this error?

mans
  • 17,104
  • 45
  • 172
  • 321
  • 1
    Does this answer your question? [error LNK2001: unresolved external symbol CATID\_AppContainerCompatible](https://stackoverflow.com/questions/18288708/error-lnk2001-unresolved-external-symbol-catid-appcontainercompatible) – Brian61354270 Jul 25 '23 at 23:13
  • @Brian61354270 I already included so the solution explained in the above answer doesn't help me – mans Jul 25 '23 at 23:17
  • 2
    So the code in your question is not the code you're trying to build? – Paul Sanders Jul 25 '23 at 23:30
  • 2
    I'm not saying that this is the issue, but it seems you missed bits: _" If you use the `DEFINE_GUID` C macro to define your GUID, you **must** include `#define INITGUID` **before** your GUID definitions"_ – Ted Lyngmo Jul 25 '23 at 23:33
  • 2
    Side note: Why do you have comments that say exactly the same as the actual code? That's a bit weird and rather redundant. – Jesper Juhl Jul 25 '23 at 23:39
  • @JesperJuhl You are right, I just copied that part of the code to fix the issue which it did not! – mans Jul 30 '23 at 02:16

1 Answers1

3

DEFINE_GUID uses kind of a semi-ugly hack that works in C, but not in C++.

When you use DEFINE_GUID, it tacks an extern on the beginning of the code it generates. In C, this is fairy harmless--you end up with what's called a "tentative definition". A tentative definition is kind of a halfway point between a declaration and a definition. On one hand, you can have multiple tentative definitions of the same name, and as long as they don't conflict (like trying to give it different types) that's all right. But it will also act as a definition if there's no non-tentative definition visible.

The closest equivalent of this in C++ would be an inline variable definition (which can also have multiple occurrences, as long as they don't conflict, and they all resolve to a single object in the end). But, as it stands right now, the macro expands to something that includes extern on the beginning, and in C++ that's strictly a declaration, not a definition, so when/if you try to use this in C++, you don't have a definition anywhere, and linking fails.

Reference

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

Putting a GUID definition outside statements that prevent multiple inclusion does not cause multiple instances of the GUID in a driver because DEFINE_GUID defines the GUID as an EXTERN_C variable. Multiple declarations of an EXTERN variable are allowed as long as the types match.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111