C++ Builder 10.3 无法从 const char[18] 分配给 const wchar_t*

问题描述

我有一个简单的目录处理代码,这里是其中的一部分。问题是,在旧版本的构建器(我猜是 6)中它运行良好,现在它抛出 [bcc32c Error] Unit1.cpp(32): assigning to 'PCZZWSTR' (aka 'const wchar_t *') from incompatible type 'const char [18]'

void __fastcall TForm1::Button2Click(TObject *Sender)
{
SHFILEOPSTRUCT fos;
String dirDest;
fos.hwnd = Handle;
//operacja kopiowania
fos.wFunc = FO_copY;
//plik źródłowy
fos.pFrom = "C:\\Melon\\AGA\\Bazy";
}

问题在于行 fos.pFrom = "C:\\Melon\\AGA\\Bazy";。我尝试使用 linkig 将 "C:\\Melon\\AGA\\Bazy" 分配给 const wchar_t*,但它告诉我它无法链接。有人知道如何修复它吗?

解决方法

您使用的是基于 TCHARSHFILEOPSTRUCT 版本,因此其字符串字段将基于 wchar_tchar,具体取决于 UNICODE分别定义与否。

在 C++Builder 6 中(其中 StringAnsiString 的别名),默认情况下未定义 UNICODE。在 C++Builder 2009 之后(其中 StringUnicodeString 的别名),UNICODE 是默认定义的,但 can be turned off 如果遗留项目需要。

由于您使用的是基于 TCHAR 的结构,因此在为其定义字符串文字时应该使用基于 TCHARTEXT() 宏,例如:

void __fastcall TForm1::Button2Click(TObject *Sender)
{
    SHFILEOPSTRUCT fos;
    fos.hwnd = Handle;
    //operacja kopiowania
    fos.wFunc = FO_COPY;
    //plik źródłowy
    fos.pFrom = TEXT("C:\\Melon\\AGA\\Bazy\0"); // don't forget the extra null terminator!
    fos.pTo = TEXT("...\0");
    ...
    SHFileOperation(&fos);
}

这适用于所有 C++Builder 版本。

另一方面,如果您尝试使用 String 变量来定义结构的字符串,则只有在预定义的 UNICODEundefined 时,该变量才有效。 2009 版本,以及在 2009 之后的版本中定义,例如:

void __fastcall TForm1::Button2Click(TObject *Sender)
{
    String dirSrc("C:\\Melon\\AGA\\Bazy\0",18); // don't forget the extra null terminator!
    String disDest(...);
    SHFILEOPSTRUCT fos;
    fos.hwnd = Handle;
    //operacja kopiowania
    fos.wFunc = FO_COPY;
    //plik źródłowy
    fos.pFrom = dirSrc.c_str();
    fos.pTo = dirDest.c_str();
    ...
    SHFileOperation(&fos);
}

如果您不想依赖 UNICODE 定义,那么您应该明确使用 ANSI 或 Unicode 版本的 SHFILEOPSTRUCT,具体取决于您是否使用 ANSI ({{1} }) 或 Unicode (char) 字符串,例如:

wchar_t
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    SHFILEOPSTRUCTA fos;
    fos.hwnd = Handle;
    //operacja kopiowania
    fos.wFunc = FO_COPY;
    //plik źródłowy
    fos.pFrom = "C:\\Melon\\AGA\\Bazy\0"; // don't forget the extra null terminator!
    fos.pTo = "...\0";
    ...
    SHFileOperationA(&fos);
}