microsoft / cpprestsdk

The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.
Other
7.95k stars 1.64k forks source link

Errors using static library cpprestsdk140 in VS2015 #344

Open koemeet opened 7 years ago

koemeet commented 7 years ago

I have been trying to get cpprestsdk to work as a static library, but when I use it I get the following:

Severity    Code    Description Project File    Line    Suppression State
Error   LNK1120 3 unresolved externals  LibTest3    C:\Users\Ik\Documents\Visual Studio 2015\Projects\LibTest3\x64\Debug\LibTest3.exe   1   
Error   LNK2019 unresolved external symbol "__declspec(dllimport) public: __cdecl web::uri::uri(wchar_t const *)" (__imp_??0uri@web@@QEAA@PEB_W@Z) referenced in function main  LibTest3    C:\Users\Ik\Documents\Visual Studio 2015\Projects\LibTest3\LibTest3\LibTest3.obj    1   
Error   LNK2019 unresolved external symbol "__declspec(dllimport) public: __cdecl web::http::client::http_client::~http_client(void)" (__imp_??1http_client@client@http@web@@QEAA@XZ) referenced in function main   LibTest3    C:\Users\Ik\Documents\Visual Studio 2015\Projects\LibTest3\LibTest3\LibTest3.obj    1   
Error   LNK2019 unresolved external symbol "__declspec(dllimport) public: __cdecl web::http::client::http_client::http_client(class web::uri const &)" (__imp_??0http_client@client@http@web@@QEAA@AEBVuri@3@@Z) referenced in function main    LibTest3    C:\Users\Ik\Documents\Visual Studio 2015\Projects\LibTest3\LibTest3\LibTest3.obj    1   

I am using the cpprestsdk140.static project and compiled as release for x64.

megaposer commented 7 years ago

You probably need to define _NO_ASYNCRTIMP when compiling against the static library project, otherwise _cpprestcompat.h will create a #define _ASYNCRTIMP __declspec(dllimport) hence leading to above errors.

I also use _NO_PPLXIMP for the same reason.

In addition:

The project file Release/src/build/vs14.static/casablanca140.static.vcxproj is not very clean/clear on this: <PreprocessorDefinitions>_NO_ASYNCRTIMP;_ASYNCRT_EXPORT;_PPLX_EXPORT;WIN32;_MBCS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>

When building the library, using _NO_ASYNCRTIMP followed by _ASYNCRT_EXPORT defeats the purpose of linking statically - it is/was probably an oversight. Based on the dynamic/static junction code in _cpprestcompat.h this will be forgiven, as _NO_ASYNCRTIMP takes precedence.

Same applies to the definition of _PPLX_EXPORT in the static project whereas it should probably be _NO_PPLXIMP.

IMHO, the project file should be adjusted to use the following preprocessor definitions: _NO_ASYNCRTIMP;_NO_PPLXIMP;WIN32;_MBCS;_USRDLL;%(PreprocessorDefinitions)

Otherwise the project will erroneously define __declspec(dllexport) when building the static library. As long as the client code building against the library uses macros to prevent dllimport, the erroneous export of symbols does not cause linkage errors and seems to be ignored.

Cheers

yintothayang commented 7 years ago

Hi!

I've tried adding _NO_ASYNCRTIMPas well as both _NO_ASYNCRTIMP;_NO_PPLXIMP; to my preprocessor definitions, in my dll project. preprocessors look like this _NO_ASYNCRTIMP;WIN32;_DEBUG;_WINDOWS;_USRDLL;REDSHELL_EXPORTS;%(PreprocessorDefinitions)

Both definition sets produce the same linkage errors:

1>cpprest_2_9.lib(web_utilities.obj) : error LNK2019: unresolved external symbol _CryptProtectMemory@12 referenced in function "public: __thiscall web::details::win32_encryption::win32_encryption(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &)" (??0win32_encryption@details@web@@QAE@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z)
1>cpprest_2_9.lib(web_utilities.obj) : error LNK2019: unresolved external symbol _CryptUnprotectMemory@12 referenced in function "public: class std::unique_ptr<class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> >,class web::details::zero_memory_deleter> __thiscall web::details::win32_encryption::decrypt(void)const " (?decrypt@win32_encryption@details@web@@QBE?AV?$unique_ptr@V?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@Vzero_memory_deleter@details@web@@@std@@XZ)
1>cpprest_2_9.lib(oauth1.obj) : error LNK2019: unresolved external symbol _BCryptOpenAlgorithmProvider@16 referenced in function "private: static class std::vector<unsigned char,class std::allocator<unsigned char> > __cdecl web::http::oauth1::experimental::oauth1_config::_hmac_sha1(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &,class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &)" (?_hmac_sha1@oauth1_config@experimental@oauth1@http@web@@CA?AV?$vector@EV?$allocator@E@std@@@std@@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@7@0@Z)
1>cpprest_2_9.lib(oauth1.obj) : error LNK2019: unresolved external symbol _BCryptGetProperty@24 referenced in function "private: static class std::vector<unsigned char,class std::allocator<unsigned char> > __cdecl web::http::oauth1::experimental::oauth1_config::_hmac_sha1(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &,class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &)" (?_hmac_sha1@oauth1_config@experimental@oauth1@http@web@@CA?AV?$vector@EV?$allocator@E@std@@@std@@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@7@0@Z)

Those are just a few linkage errors for reference ^

I am trying to link against a statically built cpprestsdk, it has been made with vcpkg using the new triplet x86-windows-static-md
process reference

Any ideas on my linkage issues?

Thanks in advance!

ras0219-msft commented 7 years ago

It looks like you also need to link some windows libraries.

From https://msdn.microsoft.com/en-us/library/windows/desktop/aa380262(v=vs.85).aspx, try adding crypt32.lib to your additional link inputs.

AhmadChaker commented 6 years ago

In addition to the _NO_ASYNCRTIMP preprocessor value, you need to add the following libs to the linker line: bcrypt.lib and winhttp.lib. This has resolved the issue for me.