-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support of UNICODE macro on Windows Visual Studio Projects #625
Comments
It's a name collision with the Windows function. You can wrap up GetObject in S3Client with a new function before including windows headers. Then call the new function instead of GetObject. |
I worked around it with the following code: Anyway the real fix is to add support of 'UNICODE' in Windows for AWS Cpp SDK. The GetObject API is already published so it cannot be renamed and most likely there are other name collisions, too. |
the support plan for unicode is to never use it anywhere unless it is utf-8. The issue here is not related to unicode at all. The issue is a name collision caused by windows' way of handling unicode. And in that case you'll need to undef the define. Our contract is that users pass const char* or std::string. We provide utilities to convert between wchar* and char* in Aws::Utils::StringUtils.
wchar and cross-platform do not mix.
…Sent from my iPhone
On Aug 2, 2017, at 3:34 PM, jace-bevo ***@***.***> wrote:
I worked around it with the following code:
std::unique_ptr< Aws::S3::S3Client > s3c(new Aws::S3::S3Client( config ));
auto getObjectOutcome = s3c.get()->GetObject( getObjectRequest );
instead of
Aws::S3::S3Client s3c( config );
auto getObjectOutcome = s3c.GetObject( getObjectRequest );
I am still not clear why this fixes the problem but it does. Maybe the preprocessor does not make the name mapping change if it is referenced from an object pointer instead of an object instance?
Anyway the real fix is to add support of 'UNICODE' in Windows for AWS Cpp SDK. The GetObject API is already published so it cannot be renamed and most likely there are other name collisions, too.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
I understand that the user is responsible for passing std::string to AWS. However, what I meant for 'UNICODE' support is the macro definition in VS project, not 'Unicode' functionality support in AWS Cpp SDK. |
When you said turn on, did you mean functions supplied by SDK also has the W/A suffix? So as to avoid name collision? Otherwise I don't see why that would help. |
What I suggest is that the SDK lets users build the project with a flag, say -DUNICODE_CHARSET_PROPERTY, when generating project files for Visual Studio with cmake so that the property of the vcxproj sets the property <Character Set>Unicode</Character Set>. |
Would that help you solve this problem and how? |
See my reply to your first comment. It is an ugly hack but at least I do not unresolved symbol errors from the linker and the binary is created fine. |
You mean settling up the vs project file to Unicode without definition of UNICODE? |
No, I mean changing my code from Aws::S3::S3Client s3c( config ); to std::unique_ptr< Aws::S3::S3Client > s3c(new Aws::S3::S3Client( config )); Since this involve changing users' source code manually everything they encounter the issue, it is not practical. |
I understand your work around here. My point is as long as there is macro definition of UNICODE and you include these Windows headers. There will be name collision anyway. No matter we default it to unicode or not. |
@jace-bevo That's why I was asking is there away to default unicode property in VS project file without macro definition of UNICODE. |
If cmaje can generate the VS project with the UNICODE macro defined, hopefully it will cause the code to be compiled with the GetObject API mapped into GetObjectW by some Window specific headers file included by the SDK. |
The VS header file that redefine GetObject is not directly included in our code. It is indirectly included by other header files we use that I do not even know which. |
It's the original definition in my project. As I said, unless you find a way to bypass the macro expand of GetObject to GetObjectW/A for your S3 function call, define UNICODE for you will do no help to solve this problem. The reason is: macro UNICODE is incorporated either by vs setting or by CMake (as you expected), so any appearance of GetObject after the windows header including, here is wingdi.h (it doesn't matter directly or indirectly included) will be replaced with GetObjectW/A. We don't have s3Client::GetObjectW/A definitions in SDK, so it will not be compiled. The work around you have done is to cheat preprocessor; other ways incuding undef UNICODE before call these functions as Jonathan said and redefine it after call; Or you can wrap it up as I said; |
When you set the <Character Set> property in the project, Visual Studio implicitly defines that macro and it affects all other include files. It should be easy to reproduce the problem I see. |
I did that for my test project and it worked fine. |
I may have a workaround for you. I had collisions with both GetMessage() and GetObject(). I also compile with VC++ Unicode enabled. My workaround is to #define NOMINMAX // required for AWS SDK to compile on Windows issue#641
#include <windows.h>
#include <atlbase.h>
#undef GetMessage // workaround for AWSError method GetMessage(), and ATL conflict
#undef GetObject // workaround for Aws::S3::S3Client::GetObject
#include <aws/s3/S3Client.h>
#include <aws/s3/model/PutObjectRequest.h>
#include <aws/transfer/TransferManager.h>
This is related to #402 |
@jace-bevo It's been a while after last reply, I think the work around should work fine. I am going to close this issue, If you have any further problem, please reopen it. |
We are using S3Client class to get and put object from Windows client. We encounter the following link error from Visual Studio 2015 on Windows 10:
6>Cloud.obj : error LNK2019: unresolved external symbol "public: virtual class Aws::Utils::Outcome<class Aws::S3::Model::GetObjectResult,class Aws::Client::AWSError > __cdecl Aws::S3::S3Client::GetObjectW(class Aws::S3::Model::GetObjectRequest const &)const " (?GetObjectW@S3Client@S3@Aws@@ueba?AV?$Outcome@VGetObjectResult@Model@S3@Aws@@v?$AWSError@W4S3Errors@S3@Aws@@@client@4@@utils@3@AEBVGetObjectRequest@Model@23@@z) referenced in function "private: int __cdecl CloudAuthenticator::RetrieveKey(class std::basic_string<char,struct std::char_traits,class std::allocator > const &)" (?RetrieveKey@CloudAuthenticator@FMS@@AEAAHAEBV?$basic_string@DU?$char_traits@D@std@@v?$allocator@D@2@@std@@@z)
As you can see that there is only Aws::S3::S3Client::GetObject, not GetObjectW API. This is because all our projects enable 'Use Unicode Character Set' of 'Character Set' property, therefore 'UNICODE' is defined and Visual Studio's header file in \Program Files(x86)\Windows Kit\8.1\incude\um\wingdi.h has the following macro
#ifdef UNICODE
#define GetObject GetObjectW
#else
#define GetObject GetObjectA
#endif // !UNICODE
This causes the preprocessor to map 'GetObject' into 'GetObjectW'.
However, none of the VS project files generated by Cmake for AWS Cpp SDK turns on so the resulting libraries do not have the correct symbol.
Is there a way we can make Cmake generate Unicode compatible project files?
The text was updated successfully, but these errors were encountered: