问题描述
所有,
我有一个导出类的静态链接库。此类包含 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 "_DEBUG" /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
。