Unicode编译器在简单函数上出错

Unicode Compiler error on simple function

本文关键字:出错 函数 简单 编译器 Unicode      更新时间:2023-10-16

Sigh

我使用的是Microsoft Visual Express C++IDE。我最近从DevC++过渡到了这个IDE。

我有一个函数在DevC++中运行得很好,但在MSVC++中,由于Unicode的原因,它无法编译(我想是?)。我需要更改什么才能编译我的函数

查看注释代码行中的编译器错误我得到

map <string, string> GetEvironmentVariablesEx()
{
   map <string, string> envVariables;
   char* environVar = GetEnvironmentStrings();  // Compile error: error C2440: 'initializing' : cannot convert from 'LPWCH' to 'char *'
   char* pos        = strchr( environVar, '' );
   // Skip over the "=::=::" of the environVar string
   if ( pos != NULL ) { environVar = ++pos; pos = strchr( environVar, '' ); }
   else return envVariables;
   while ( true )
   {
       char* delim    = strchr( environVar, '=' );
       if ( delim == NULL )
            break;
       string variable = string( environVar, strlen(environVar)-strlen(delim) );
       string value    = string( ++delim );
       envVariables.insert( pair<string, string>(variable, value) );
       environVar = ++pos;
       // find the "" that identifies the end of environVar
       if ( pos != NULL && *pos == 0 ) { break; }
       pos = strchr( environVar, '' );
   }
   FreeEnvironmentStrings( environVar ); 
   return envVariables;       
}

PS:因为这个应用程序是用Unicode编译的,这是否意味着它可以在ANSII计算机上工作;UNICODE计算机-所以我的应用程序将能够在国际上运行?

Visual C++正在尝试编译支持Unicode的程序。在后台,这是通过#defineUNICODE_UNICODE宏执行的。这反过来又会导致程序使用Win32函数的Unicode变体。

每个Win32函数(接受或返回字符串)都有两种变体。例如,GetEnvironmentStrings实际上是两个函数:GetEnvironmentStringsAGetEnvironmentStringsWGetEnvironmentStrings解析为其中之一,这取决于是否定义了UNICODE宏。

因此,您的程序是为Unicode编译的,编译器无法弄清楚如何将(Unicode)GetEnvironmentStringsW(它是LPWCH——实际上是WCHAR *)的结果放入(ANSI)std::string中。

您可以执行以下操作之一(或组合):

  1. 将整个程序转换为Unicode(开始使用std::wstring
  2. 明确使用GetEnvironmentStringsA
  3. 改为对非Unicode进行重新编译
  4. 在Windows中使用TCHAR支持。您需要定义一个tstring类型

这不是一个详尽的清单。

回复:

因为这个应用程序是用Unicode编译的,这是否意味着它可以在ANSII计算机上工作;UNICODE计算机-所以我的应用程序将能够在国际上运行?

计算机不是ANSI或Unicode。操作系统是。上一个不支持Unicode的Windows版本是Workgroups的Windows 3.11。

也就是说,仅仅为Unicode进行编译并不能使您的应用程序在国际上运行。它可以正常工作,但Unicode只涵盖字符集。你仍然需要担心翻译,日期和时间格式,数字格式,不同的日历。国际化、本地化和全球化不仅仅是支持Unicode。

您的项目是UNICODE构建,并且您使用ANSI字符串,首先要做的是将char变量替换为TCHAR,然后重试。

正如@David Heffernan恰当地建议的那样,您将不得不切换到wstring,并从您使用的标准库中适当地更改库函数。

您正在编译针对Unicode字符串但声明ANSI字符串变量的应用程序。如果您想要Unicode,那么您需要在标准库中使用宽字符、wstring和相应的字符串处理例程。

如果您还没有准备好应对这种变化,那么将项目选项从Unicode更改为MBCS,这是获得ANSI构建的稍微不直观的方法。

这不是你的程序是否能在不同的Windows盒子上正确运行,而是关于Windows进行的转换。一个以一个或多个字符串为参数的Windows API,它将有两个版本:ANSI和Unicode。尽管并非所有函数都有两种变体(比如ReadDirectoryChangesW,它只是Unicode)。

当您调用ANSI版本时,Windows需要将该ANSI字符串复制到Unicode字符串中。是的,它需要内存分配,将1字节的ANSI字符转换为2字节的Unicode字符。如果该函数将一个或多个字符串作为输出,则需要将Unicode转换为ANSI。

这显然会耗费时间和内存,并使程序运行缓慢。此外,许多ANSI版本会/可能会修改传递的ANSI字符串,并且需要而不是传递字符串常量。如果您传递字符串常量(如CreateProcessA的硬编码可执行路径),则会导致某些Win32内存异常。

因此,最好将所有ANSI项目转换为Unicode。

PS:对字符串使用_T、_TEXT甚至L都是令人沮丧的。为什么VC++编译器不能支持将所有"字符串"视为L"字符串"的选项?:[