1
votes

ALL,

I have a static link library which exports a class. This class contains a member of std::mutex.

When I link this library to my main project there is no problem, but when I try to link the library to dynamic link library in the same project I'm getting the undefined external symbol.

I double check and all the libraries I link are the same.

Whats weird is that the linker complain about the member and not the class itself.

What could be the issue?

TIA!

P.S. if it matter - I'm working with msvc 2017 on Windows 8.1.

P.P.S.:

Command to build the application:

/GS /analyze- /W4 /Zc:wchar_t /I"C:\Program Files (x86)\Visual Leak Detector\include" /I"..\dbinterface" /I"..\libdbwindow\res\gui" /I"c:\wxWidgets\lib\vc_dll\mswud" /I"c:\wxWidgets\include" /I"." /I"C:\Program Files (x86)\Visual Leak Detector\include" /Zi /Gm- /Od /Fd"vc_mswuddll\docview.pdb" /Zc:inline /fp:precise /D "WIN32" /D "_DEBUG" /D "_CRT_SECURE_NO_DEPRECATE=1" /D "_CRT_NON_CONFORMING_SWPRINTFS=1" /D "_SCL_SECURE_NO_WARNINGS=1" /D "WXMSW" /D "_UNICODE" /D "WXUSINGDLL" /D "_WINDOWS" /D "NOPCH" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /FC /Fa"vc_mswuddll" /EHsc /nologo /Fo"vc_mswuddll\docview" /Fp"vc_mswuddll\docview.pch" /diagnostics:classic

Command to build the library:

/GS /analyze- /W4 /Zc:wchar_t /I"C:\Program Files (x86)\Visual Leak Detector\include" /I"..\dbinterface" /I"..\libfieldswindow" /I"..\libshapeframework" /I"..\libpropertypages" /I"..\libpropertieshandlers" /I"c:\wxWidgets\lib\vc_dll\mswud" /I"c:\wxWidgets\include" /I"." /Zi /Gm- /Od /Fd"vc_mswuddll\tabledataedit.pdb" /Zc:inline /fp:precise /D "MEMORYLEAKS" /D "WIN32" /D "_USRDLL" /D "DLL_EXPORTS" /D "_DEBUG" /D "_CRT_SECURE_NO_DEPRECATE=1" /D "_CRT_NON_CONFORMING_SWPRINTFS=1" /D "_SCL_SECURE_NO_WARNINGS=1" /D "WXMSW" /D "_UNICODE" /D "WXUSINGDLL" /D "MY_DLL_BUILDING" /D "_WINDLL" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /GR /Gd /Oy- /MDd /FC /Fa"vc_mswuddll" /EHsc /nologo /Fo"vc_mswuddll" /Fp"vc_mswuddll\tabledataedit.pch" /diagnostics:classic

The symbol is declared as

class __declspec(dllexport) Database
{
protected:
    struct Impl;
    Impl *pimpl;
    // more members here
};

struct Database::Impl
{
    static std::mutex my_mutex;
    // more members here
};

EDIT:

c:\Users\Igor\OneDrive\Documents\dbhandler_app\dbhandler\Debug>dumpbin /symbols
dbinterface.lib
Microsoft (R) COFF/PE Dumper Version 14.16.27045.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file dbinterface.lib

File Type: LIBRARY

COFF SYMBOL TABLE
000 010569A5 ABS    notype       Static       | @comp.id
001 80000191 ABS    notype       Static       | @feat.00
002 00000000 SECT1  notype       Static       | .drectve
    Section length   41, #relocs    0, #linenums    0, checksum        0
    Relocation CRC 00000000
005 00000000 SECT2  notype       Static       | .debug$S
    Section length 23FC, #relocs    2, #linenums    0, checksum        0
    Relocation CRC 3EE39AC2
008 00000000 SECT3  notype       Static       | .debug$T
    Section length   70, #relocs    0, #linenums    0, checksum        0
    Relocation CRC 00000000
00B 00000000 SECT4  notype       Static       | .bss
    Section length    4, #relocs    0, #linenums    0, checksum        0, select
ion    2 (pick any)
    Relocation CRC 00000000
00E 00000000 SECT4  notype       External     | ___@@_PchSym_@00@UfhvihUrtliUlmv
wirevUwlxfnvmghUwyszmwoviPzkkUwyrmgviuzxvUwvyftUhgwzucOlyq@4B2008FD98C1DD4
00F 00000000 SECT5  notype       Static       | .msvcjmc
    Section length    1, #relocs    0, #linenums    0, checksum 77073096
    Relocation CRC 00000000
012 00000000 SECT5  notype       Static       | __BDBDE527_dbinterface@pch
013 00000000 SECT6  notype       Static       | .debug$S
    Section length   84, #relocs    2, #linenums    0, checksum        0, select
ion    5 (pick associative Section 0x4)
    Relocation CRC 4D9779EE
016 00000000 SECT7  notype       Static       | .chks64
    Section length   38, #relocs    0, #linenums    0, checksum        0
    Relocation CRC 00000000

String Table Size = 0x8A bytes

  Summary

           4 .bss
          38 .chks64
        2480 .debug$S
          70 .debug$T
          41 .drectve
           1 .msvcjmc

EDIT 1:

Link command for application:

/OUT:"vc_mswuddll\docview.exe" /MANIFEST /NXCOMPAT /PDB:"vc_mswuddll\docview.pdb" /DYNAMICBASE "vld.lib" "dbinterface.lib" "wxmsw31ud_core.lib" "wxbase31ud.lib" "wxtiffd.lib" "wxjpegd.lib" "wxpngd.lib" "wxzlibd.lib" "wxregexud.lib" "wxexpatd.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "comdlg32.lib" "winspool.lib" "winmm.lib" "shell32.lib" "shlwapi.lib" "comctl32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "rpcrt4.lib" "advapi32.lib" "version.lib" "wsock32.lib" "wininet.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X86 /SAFESEH /INCREMENTAL /PGD:"vc_mswuddll\docview.pgd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"vc_mswuddll\docview.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"C:\Program Files (x86)\Visual Leak Detector\lib\Win32" /LIBPATH:".\Debug" /LIBPATH:"c:\wxWidgets\lib\vc_dll" /TLBID:1

Link command for the dynamic library:

/OUT:"..\dbhandler\vc_mswuddll\tabledataedit.dll" /MANIFEST /NXCOMPAT /PDB:"vc_mswuddll\tabledataedit.pdb" /DYNAMICBASE "vld.lib" "dbinterface.lib" "fieldswindow.lib" "shapeframework.lib" "propertieshandlers.lib" "propertypages.lib" "wxmsw31ud_adv.lib" "wxmsw31ud_core.lib" "wxbase31ud.lib" "wxtiffd.lib" "wxjpegd.lib" "wxpngd.lib" "wxzlibd.lib" "wxregexud.lib" "wxexpatd.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "comdlg32.lib" "winspool.lib" "winmm.lib" "shell32.lib" "shlwapi.lib" "comctl32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "rpcrt4.lib" "advapi32.lib" "version.lib" "wsock32.lib" "wininet.lib" "odbc32.lib" "odbccp32.lib" /IMPLIB:"vc_mswuddll\tabledataedit.lib" /DEBUG /DLL /MACHINE:X86 /SAFESEH /INCREMENTAL /PGD:"vc_mswuddll\tabledataedit.pgd" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"vc_mswuddll\tabledataedit.dll.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"C:\Program Files (x86)\Visual Leak Detector\lib\Win32" /LIBPATH:"..\dbhandler\Debug" /LIBPATH:"..\libfieldswindow\vc_mswuddll" /LIBPATH:"..\libshapeframework\vc_mswuddll" /LIBPATH:"..\libpropertieshandlers\vc_mswuddll" /LIBPATH:"..\libpropertypages\vc_mswuddll" /LIBPATH:"c:\wxWidgets\lib\vc_dll" /TLBID:1

EDIT:

And here is the result of dumpbin with the change:

c:\Users\Igor\OneDrive\Documents\dbhandler_app\dbhandler\Debug>dumpbin /symbols
dbinterface.lib
Microsoft (R) COFF/PE Dumper Version 14.16.27045.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file dbinterface.lib

File Type: LIBRARY

COFF SYMBOL TABLE
000 010569A5 ABS    notype       Static       | @comp.id
001 80000191 ABS    notype       Static       | @feat.00
002 00000000 SECT1  notype       Static       | .drectve
    Section length   41, #relocs    0, #linenums    0, checksum        0
    Relocation CRC 00000000
005 00000000 SECT2  notype       Static       | .debug$S
    Section length 23FC, #relocs    2, #linenums    0, checksum        0
    Relocation CRC 3EE39AC2
008 00000000 SECT3  notype       Static       | .debug$T
    Section length   70, #relocs    0, #linenums    0, checksum        0
    Relocation CRC 00000000
00B 00000000 SECT4  notype       Static       | .bss
    Section length    4, #relocs    0, #linenums    0, checksum        0, select
ion    2 (pick any)
    Relocation CRC 00000000
00E 00000000 SECT4  notype       External     | ___@@_PchSym_@00@UfhvihUrtliUlmv
wirevUwlxfnvmghUwyszmwoviPzkkUwyrmgviuzxvUwvyftUhgwzucOlyq@4B2008FD98C1DD4
00F 00000000 SECT5  notype       Static       | .msvcjmc
    Section length    1, #relocs    0, #linenums    0, checksum 77073096
    Relocation CRC 00000000
012 00000000 SECT5  notype       Static       | __BDBDE527_dbinterface@pch
013 00000000 SECT6  notype       Static       | .debug$S
    Section length   84, #relocs    2, #linenums    0, checksum        0, select
ion    5 (pick associative Section 0x4)
    Relocation CRC 4D9779EE
016 00000000 SECT7  notype       Static       | .chks64
    Section length   38, #relocs    0, #linenums    0, checksum        0
    Relocation CRC 00000000

String Table Size = 0x8A bytes

  Summary

           4 .bss
          38 .chks64
        2480 .debug$S
          70 .debug$T
          41 .drectve
           1 .msvcjmc
1

1 Answers

0
votes

__declspec(dllexport) means the question is about an import library of a DLL (not a "static link library"), and in that case the error is due to my_mutex not being exported. This could be resolved by exporting:

  • either the entire nested class;

    struct __declspec(dllexport) Database::Impl
    {
      static std::mutex my_mutex;
      // more members here
    };
    
  • or just the static variable in question.

    struct Database::Impl
    {
      static __declspec(dllexport) std::mutex my_mutex;
      // more members here
    };
    

This should work for the std::mutex used in the example here, but will run into C4251 with other STL templatized classes. That, in turn, can be worked around (see One way of eliminating C4251 warning when using stl-classes in the dll-interface for example), but a better solution might be to rearrange the APIs so that my_mutex does not need to be exported to begin with.