简体   繁体   English

在C ++ Builder和VC ++中使用std :: string的区别

[英]Differences using std::string in C++ Builder and VC++

since I can get hands on the new RAD Studio Xe4 I thought I'd give it a try. 因为我可以使用新的RAD Studio Xe4,所以我想尝试一下。 Unfortunatly, I am not so experienced with C++ and therefore I was wondering why the Code that works perfectly fine in VC++ doesn't work at all in C++ Builder. 不幸的是,我对C ++并没有那么丰富的经验,因此我想知道为什么在VC ++中完美运行的代码在C ++ Builder中根本无法正常工作。 Most of the problems are converting different var-types. 大多数问题是转换不同的var类型。 For example : 例如 :

std::string Test = " ";
GetFileAttributes(Test.c_str());

works in VC++ but in C++ Builder it won't compile, telling me "E2034 Cannot convert 'const char *' to 'wchar_t *'. Am I missing something? What is the reason that doesn't work the same on all compilers the same? Thanks 在VC ++中工作,但在C ++ Builder中将无法编译,并告诉我“ E2034无法将'const char *'转换为'wchar_t *'。我丢失了什么吗?是什么原因导致在所有编译器上均不相同?一样吗谢谢

Welcome to Windows Unicode/ASCII hell. 欢迎使用Windows Unicode / ASCII。

The function 功能

GetFileAttributes

is actually a macro defined to either GetFileAttributesA or GetFileAttributesW depending on if you have _UNICODE (or was it UNICODE , or both?) defined when you include the Windows headers. 实际上是定义为GetFileAttributesAGetFileAttributesW的宏,具体取决于您在包含Windows标头时是否定义了_UNICODE (或者是UNICODE ,或两者都定义了)。 The *A variants take char* and related arguments, the *W functions take wchar_t* and related arguments. *A变量采用char*和相关参数, *W函数采用wchar_t*和相关参数。

I suggest calling only the wide *W variants directly in new code. 我建议直接在新代码中仅调用宽*W变体。 This would mean switching to std::wstring for Windows only code and some well-thought out design choices for a cross-platform application. 这将意味着仅针对Windows代码切换到std :: wstring,并为跨平台应用程序选择一些经过深思熟虑的设计选择。

Your C++ Builder config is set to use UNICODE character set, which means that Win32 APIs are resolved to their wide character versions. 您的C ++ Builder配置设置为使用UNICODE字符集,这意味着Win32 API被解析为其宽字符版本。 Therefore you need to use wide char strings in your C++ code. 因此,您需要在C ++代码中使用宽字符字符串。 If you would set your VS config to use UNICODE, you would get the same error. 如果将VS配置设置为使用UNICODE,则会出现相同的错误。

You can try this: 您可以尝试以下方法:

// wstring = basic_string<wchar_t>
// _T macro ensures that the specified literal is a wide char literal
std::wstring Test = _T(" ");     
GetFileAttributes(Test.c_str()); // c_str now returns const wchar_t*, not const char* 

See more details about _T/_TEXT macros here: http://docwiki.embarcadero.com/RADStudio/XE3/en/TCHAR_Mapping 在此处查看有关_T / _TEXT宏的更多详细信息: http ://docwiki.embarcadero.com/RADStudio/XE3/en/TCHAR_Mapping

You have defined _UNICODE and/or UNICODE in Builder and not defined it in VC. 您已在Builder中定义了_UNICODE和/或UNICODE ,而未在VC中定义。

Most Windows APIs come in 2 flavours the ANSI flavour and the UNICODE flavour. 大多数Windows API有ANSI风味和UNICODE风味两种。

For, when you call SetWindowText , there really is no SetWindowText functions. 因为,当您调用SetWindowText ,实际上没有SetWindowText函数。 Instead there are 2 different functions - SetWindowTextA which takes an ANSI string and - SetWindowTextW which takes a UNICODE string. 代替有2个不同的功能- SetWindowTextA这需要ANSI字符串和- SetWindowTextW这需要一个Unicode字符串。

If your program is compiled with /DUNICODE /D_UNICODE, SetWindowText maps to SetWindowTextW which expects a const wchar_t *`. 如果您的程序是使用/ DUNICODE / D_UNICODE编译的,则SetWindowText映射到which expects a const wchar_t *`的SetWindowTextW。

If your program is compiled without these macros defined, it maps to SetWindowTextA which takes a const char * . 如果您的程序在未定义这些宏的情况下进行编译,则它将映射到采用const char * SetWindowTextA

The windows headers typically do something like this to make this happen. Windows标头通常会这样做,以实现此目的。

#ifdef UNICODE
#define SetWindowText  SetWindowTextW
#else
#define SetWindowText  SetWindowTextA
#endif 

Likewise, there are 2 GetFileAttributes . 同样,有2个GetFileAttributes

DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName);

DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName);

In VC, you haven't defined UNICODE/_UNICODE & hence you are able to pass string::c_str() which returns a char * . 在VC中,您尚未定义UNICODE / _UNICODE,因此您可以传递string::c_str() ,该string::c_str()返回char *

In Builder, you probably have defined UNICODE/_UNICODE & it expects a wchar_t * . 在Builder中,您可能已定义UNICODE / _UNICODE,并且期望使用wchar_t *

You may not have done this UNICODE/_UNICODE thing explicitly - may be the IDE is doing it for you - so check the options in the IDE. 您可能没有明确地完成此UNICODE / _UNICODE操作-可能是IDE正在为您做-因此请检查IDE中的选项。

You have many ways of fixing this 您有多种方法可以解决此问题

  • find the UNICODE/_UNICODE option in the IDE and disable it. 在IDE中找到UNICODE / _UNICODE选项并将其禁用。

or 要么

  • use std::w_string - then c_str() will return a wchar_t * 使用std::w_string然后c_str()将返回wchar_t *

or 要么

  • Call GetFileAttributesA directly instead of GetFileAttributes - you will need to do this for every other Windows API which comes with these 2 variants. 直接调用GetFileAttributesA而不是GetFileAttributes您需要对这2个变体附带的所有其他Windows API进行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM