4

I'm using the boost libraries as installed by the BoostPro Computing installer. I'm using VS 2010 on a Windows 7 64-bit machine. I want to link to boost dynamically, so I selected the first two options in the installer (Multithreaded Debug DLL and Multithreaded DLL, I believe they were called). An example of some installed libs are:

boost_bzip2-vc100-mt-1_51.lib
boost_bzip2-vc100-mt-gd-1_51.lib

When linking to boost in my project, I also made sure to define BOOST_ALL_DYN_LINK. I'm specifically using the filesystem toolset.

When I turn on BOOST_LIB_DIAGNOSTIC I see the following messages in the build output:

1>  Linking to lib file: boost_filesystem-vc100-mt-gd-1_51.lib
1>  Linking to lib file: boost_system-vc100-mt-gd-1_51.lib

However, those are quickly followed up by:

1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const __thiscall boost::filesystem::path::string(void)const " (__imp_?string@path@filesystem@boost@@QBE?BV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall boost::filesystem::path::~path(void)" (__imp_??1path@filesystem@boost@@QAE@XZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) class boost::filesystem::path __cdecl boost::filesystem::detail::unique_path(class boost::filesystem::path const &,class boost::system::error_code *)" (__imp_?unique_path@detail@filesystem@boost@@YA?AVpath@23@ABV423@PAVerror_code@system@3@@Z) referenced in function "class boost::filesystem::path __cdecl boost::filesystem::unique_path(class boost::filesystem::path const &)" (?unique_path@filesystem@boost@@YA?AVpath@12@ABV312@@Z)
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class std::codecvt<wchar_t,char,int> const & __cdecl boost::filesystem::path::codecvt(void)" (__imp_?codecvt@path@filesystem@boost@@SAABV?$codecvt@_WDH@std@@XZ) referenced in function "public: __thiscall boost::filesystem::path::path<char const [20]>(char const (&)[20],void *)" (??$?0$$BY0BE@$$CBD@path@filesystem@boost@@QAE@AAY0BE@$$CBDPAX@Z)
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl boost::filesystem::path_traits::convert(char const *,char const *,class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > &,class std::codecvt<wchar_t,char,int> const &)" (__imp_?convert@path_traits@filesystem@boost@@YAXPBD0AAV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@ABV?$codecvt@_WDH@5@@Z) referenced in function "void __cdecl boost::filesystem::path_traits::dispatch<class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > >(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > &,class std::codecvt<wchar_t,char,int> const &)" (??$dispatch@V?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@path_traits@filesystem@boost@@YAXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@4@ABV?$codecvt@_WDH@4@@Z)
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) class boost::system::error_category const & __cdecl boost::system::generic_category(void)" (__imp_?generic_category@system@boost@@YAABVerror_category@12@XZ) referenced in function "void __cdecl boost::system::`dynamic initializer for 'posix_category''(void)" (??__Eposix_category@system@boost@@YAXXZ)
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) class boost::system::error_category const & __cdecl boost::system::system_category(void)" (__imp_?system_category@system@boost@@YAABVerror_category@12@XZ) referenced in function "void __cdecl boost::system::`dynamic initializer for 'native_ecat''(void)" (??__Enative_ecat@system@boost@@YAXXZ)

Shouldn't the auto-link.hpp be taking care of my linking for me? I'm not specifically requesting anything be linked to the project because the auto linker appears to be identifying everything correctly. So how is it that I'm missing these things? Also, they're declared as dllimport, so shouldn't the linker be leaving them alone and expect them to be discovered at runtime?

Thanks!

UPDATE: I decided to dive in on the second linker error. It's basically saying that it can't find the destructor for the path class. After running dumpbin on the filesystem library, I noticed that this line is in the file:

??1path@filesystem@boost@@QEAA@XZ (public: __cdecl boost::filesystem::path::~path(void))

But this obviously doesn't match with what the linker is looking for, which is this:

"__declspec(dllimport) public: __thiscall boost::filesystem::path::~path(void)" (__imp_??1path@filesystem@boost@@QAE@XZ)

Notice that the linker is looking for a DLL-import version, but the library itself doesn't seem to be providing one... not sure where to go from here, but it seems like important information!

aardvarkk
  • 14,955
  • 7
  • 67
  • 96

3 Answers3

5

For me, this was because the "treat wchar_t as built-in type" option was set to false, so that wchar_t was compiled as unsigned short.

Tim Sylvester
  • 22,897
  • 2
  • 80
  • 94
  • anyway at least in VS2015 it is enabled by default: https://msdn.microsoft.com/en-us/library/dh8che7s.aspx – Antonino Aug 10 '16 at 04:01
4

Assuming you have those .lib already compiled you need to make sure that the .lib files are in the Library path (look VC++ Directories->Library path).

The compiler will place a link to the DLLs at compile time, using the .lib to discover the correct entry points etc, so they can be loaded efficiently when the EXE/DLL starts up at run-time.

The type of runtime DLL discovery you're talking about requires LoadLibrary + GetProcAddress type code, which Boost doesn't support.

(Static linking actually puts code from a statcially compiled .lib code into your DLL/EXE.)

EDIT: Also, check you're using the correct .lib files for your archicture, e.g. 32-bit or 64-bit. That would cause a similar error with the signatures.

dumpbin /headers 

will tell you which 'machine' type the .lib has been built for (the first section of the dumpbin output).

snowdude
  • 3,854
  • 1
  • 18
  • 27
  • Thanks for the suggestion. The libraries are indeed there -- I tested deleting one of the libraries mentioned in the "Linking to lib...", and I get an error saying the file is missing. So the files mentioned are indeed being correctly linked to, but it seems like some of the symbols or definitions are missing? – aardvarkk Oct 03 '12 at 19:31
  • Were the .libs compiled with Unicode because it looks like you're linking a multi-byte character set? If you do a dumpbin /ALL on the .lib you can see what's being exported. If all the classes are using wchar_t you know the problem. – snowdude Oct 03 '12 at 19:37
  • Hrm... switching the project to use Unicode didn't work... same linker errors! – aardvarkk Oct 03 '12 at 19:48
  • What do you have for your calling convention settings (C++->Advanced)? The signatures of methods are slightly different and it looks like it's calling convention related. – snowdude Oct 04 '12 at 10:24
  • 1
    Another thought... are you sure you're using the 32-bit .lib files. That would cause a similar error with the signatures. – snowdude Oct 04 '12 at 10:39
  • The calling convention was set to default (__cdecl). I'm not sure whether or not I'm using 32-bit .lib files -- there's no option in the BoostPro install. I determined that even *without* dynamic linking, I was getting these linker errors. The only way around it I've found so far is to build boost myself using `b2`. I just couldn't get the BoostPro install working at all without the linker errors, but when I build it myself it seems to link fine. It's too bad I couldn't figure out the exact problem though... it may be 32/64-bit related as you've mentioned, but how do I check that? – aardvarkk Oct 04 '12 at 14:06
  • "dumpbin /headers" the first section of the output will tell you. – snowdude Oct 04 '12 at 15:40
  • I believe the issue came down to C/C++ runtime linking problems. – aardvarkk Nov 20 '12 at 15:04
  • I've just suffered the same problem and it was "solved" by changing the Solution Platform from Win32 (has always been the standard) to x64. There were no clues to this anywhere in the Boost guides, nor the compiling/linking errors. C++ has a long way to go in userfriendliness. – Gaminic Mar 27 '14 at 15:47
  • It's also worth mentioning that you need to use libs/dlls built by the same compiler version. If you're compiling boost yourself, and using a guide, the b2 toolset option might be shown simply ass "toolset=msvc" That will automatically pick the newest compiler, which might not be the one you want. To specify, change it to "toolset=msvc-x.xx" where x.xx is the msvc compiler version (i.e. 12.0 for VS 2013) – Digital_Utopia Mar 21 '19 at 13:55
1

There is (from your unresolved list) a difference in calling convention. This will cause the symbols to not match. I've found that 1.54.0 will not compile all libraries if you try to compile with other than _cdecl as the calling convention on Windows. Windows likes lots of different calling conventions, and they will not match (_cdecl /Gd, __stdcall /Gz, __FASTCALL /Gr) Also, at least in 1.54.0 I've notice that some libraries require wchar_t to be treated as a built-in type (Windows VS option /Zc:wchar_t) (boost::log library for sure). This will also cause unresolved errors as a wchar_t does not match unsigned short in this case.

dabble53
  • 91
  • 1
  • 3