c++cwinapidia-sdk

Building DIA code fails with LNK2001: unresolved external symbol _CLSID_DiaSource


Following the instructions from this Q&A this program compiles but fails to link:

#include "dia2.h"

int main() { auto const clsid { CLSID_DiaSource }; }

The full error diagnostic is

main.obj : error LNK2001: unresolved external symbol _CLSID_DiaSource

Where is this symbol defined and what do I need to do to make the linker happy?


Solution

  • DIA's interface and class IDs are defined in a static library called diaguids.lib. It needs to be passed as an input to the linker. An easy way to do this is via a comment pragma:

    #include "dia2.h"
    #pragma comment(lib, "diaguids")
    
    int main() { auto const clsid { CLSID_DiaSource }; }
    

    This isn't sufficient, though. The linker will still error out with

    LINK : fatal error LNK1104: cannot open file 'diaguids.lib'
    

    To fix this the (platform-specific) library path must be set in the build environment. The DIA SDK chose an odd layout and naming scheme making this somewhat tedious to set up. This isn't just me, either: The Dia2dump sample fails to link for any platform that isn't x86.

    In Visual Studio, the library directory can be added by right-clicking the project, selecting "Properties", and navigating to "Configuration Properties" -> "VC++ Directories". The "Library Directories" configuration needs to be updated to include a directory according to this table:

    Platform Directory
    x86 $(VSInstallDir)DIA SDK\lib
    x86_64 $(VSInstallDir)DIA SDK\lib\amd64
    ARM $(VSInstallDir)DIA SDK\lib\arm
    ARM64 $(VSInstallDir)DIA SDK\lib\arm64

    With the library paths properly added for all target platforms the program now successfully links.


    As an alternative to setting up the linker environment, this particular issue can also be solved by the compiler: The Microsoft-specific __uuidof operator can retrieve the GUID for interface and class IDs:

    #include "dia2.h"
    
    int main() { auto const clsid { __uuidof(DiaSource) }; }
    

    This will work with MSVC and Clang, though Clang will issue a warning.

    Setting up the linker environment can (be made to) work with any compiler and linker, so that places fewer restrictions on users. And it is strictly required in case you need access to other symbols implemented in diaguids.lib (such as NoRegCoCreate()).