dll 链接期间未解析的外部符号

问题描述

所有,

我有一个导出类的静态链接库。此类包含 std::mutex 的成员。

当我将这个库链接到我的主项目时没有问题,但是当我尝试将库链接到同一个项目中的动态链接库时,我得到了未定义的外部符号。

我仔细检查,我链接的所有库都是一样的。

奇怪的是链接器抱怨的是成员而不是类本身。

可能是什么问题?

TIA!

附言如果有关系 - 我正在 Windows 8.1 上使用 msvc 2017。

P.P.S.:

构建应用程序的命令:

/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 "WXUSINGWINDO" /D "WXUSINGWINDO" /D /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

构建库的命令:

/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 "_D​​EBUG" /D "_CRT_SECURE_NO_DEPRECATE=1" /D "_CRT_NON_CONFORMING_SWPRINTFS=1" /D "_SCL_SECURE_NO_WARNINGS=1" /D "WxmsW" /D "_UNICODE" /D "/WXUSING" 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

符号声明为

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

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

编辑:

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,checksum        0
    Relocation CRC 3EE39AC2
008 00000000 SECT3  notype       Static       | .debug$T
    Section length   70,checksum        0
    Relocation CRC 00000000
00B 00000000 SECT4  notype       Static       | .bss
    Section length    4,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,checksum 77073096
    Relocation CRC 00000000
012 00000000 SECT5  notype       Static       | __BDBDE527_dbinterface@pch
013 00000000 SECT6  notype       Static       | .debug$S
    Section length   84,select
ion    5 (pick associative Section 0x4)
    Relocation CRC 4D9779EE
016 00000000 SECT7  notype       Static       | .chks64
    Section length   38,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:

应用程序的链接命令:

/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

动态库的链接命令:

/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 \D ebug" /LIBPATH:"..\libfieldswindow\vc_mswuddll" /LIBPATH:"..\libshapeframework\vc_mswuddll" /LIBPATH:"..\libpropertieshandlers\vc_mswuddll" /LIBPATH:"..\libpropertypages\vc_mswuddll" /LIBPATH: c:\wxWidgets\lib\vc_dll" /TLBID:1

编辑:

这是 dumpbin 更改后的结果:

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,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

解决方法

__declspec(dllexport) 表示问题是关于 DLL 的导入库(不是“静态链接库”),在这种情况下,错误是由于 my_mutex没有被出口。这可以通过导出来解决:

  • 要么是整个嵌套类;

    struct __declspec(dllexport) Database::Impl
    {
      static std::mutex my_mutex;
      // more members here
    };
    
  • 或者只是有问题的静态变量。

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

这应该适用于此处示例中使用的 std::mutex,但会遇到其他 STL 模板化类的 C4251。反过来,这可以解决(例如,请参阅 One way of eliminating C4251 warning when using stl-classes in the dll-interface),但更好的解决方案可能是重新排列 API,这样就无需导出 my_mutex