2

I have a function which takes two CHAR* as input viz. int _stdcall FileTrans(char* InFile, char* OutFile) in a DLL project.

In the function I'm just calling CopyFile(InFile, OutFile, false); after some process (not related to the files). But it says that it needs both inputs as LPCWSTR. I Googled it but couldn't find anything very interesting.

4

1 回答 1

7

与所有接受字符串参数的 Windows API 函数一样,CopyFile 函数实际上有两种变体:

  • CopyFileA 是 ANSI 版本,它采用系统默认字符集中的(非 Unicode)字符串。基本上,它接受 type 的参数const char*,但 Windows 标头LPCSTR为此使用 typedef。

  • CopyFileW 是宽版本,它采用Unicode字符串。为了做到这一点,它接受 type 的参数w_char*,但 Windows 头文件LPCWSTR为此使用 typedef(注意 typedef 中的附加内容W)。

然后,根据是否UNICODE为您的项目定义了预处理器宏(在包含 Windows 标头之前的代码中,或在 Visual Studio 中的项目属性中),Windows 标头将未修饰的 CopyFile 定义为 CopyFileA 或 CopyFileW。自然,如果UNICODE定义了,CopyFile 将被定义为Unicode 版本的CopyFileW。否则,它将被定义为 CopyFileA。这个想法是对通用 CopyFile 函数的调用在编译时自动解析为正确的变体。

当然,既然您了解了所有这些,您几乎可以忘记它。在现代 Windows 编程中,完全没有理由调用旧 ANSI 版本的函数或处理窄字符串。忘记它char*甚至可以用作字符串类型——那些字符串对你来说已经死了。从现在开始,您将要使用的唯一字符串是由字符组成的 Unicode 字符串wchar_t。因此,UNICODE应该始终为您的代码定义符号,并且您应该只使用WWindows API 函数的版本。

再次查看 CopyFileW 函数的原型(与您在UNICODE定义时调用 CopyFile 时得到的相同),我们看到:

BOOL WINAPI CopyFile(LPCWSTR lpExistingFileName,
                     LPCWSTR lpNewFileName,
                     BOOL bFailIfExists);

回想一下您在上面学到LPCWSTR的只是 typedef 的同义词const wchar_t*,它是由宽字符组成的 C 样式字符串。您已经知道为什么要标记参数const:因为该函数不会修改这些值。

而且因为您在上面还了解到这些是您应该再使用的唯一类型的字符串,下一步是修改您的 FileTrans 函数以接受宽字符串(const如果它不打算修改它们,则制作它们):

int _stdcall FileTrans(const wchar_t* InFile, const wchar_t* OutFile);

现在,从 FileTrans 内部,您可以毫无问题地调用 CopyFile,因为您拥有正确类型的字符串。


但是有一点免费的额外建议:永远不要在 C++ 中使用原始 C 风格的字符串。std始终使用标头在命名空间中定义的 C++ 字符串类<string>

这个类有两个常见的变体,std::stringstd::wstring. 和以前一样,thew指的是宽字符串,这是您想在 Windows 中使用的唯一类型。整个代码库std::wstring的新替代品也是如此。CHAR*

将 FileTrans 函数的声明更改为如下所示:

#include <string>

// ...some other stuff...

int __stdcall FileTrans(const std::wstring& InFile, const std::wstring& OutFile);

请注意,我已将您的原始参数更改为对对象CHAR*的常量引用。std::wstring常量引用在这里工作得很好,因为您不会在函数内部更改这些值中的任何一个。

如果您不清楚常量的含义、如何使用引用或类类型通常如何在 C++ 中工作,请查阅您最喜欢的 C++ 书籍)——这是所有 C++ 程序员都需要的知识。请记住,C++ 与 C 语言不同,因此不适用相同的习语。在许多情况下,有更好的方法来做事,这当然是这种情况的一个例子。

于 2013-03-17T07:36:33.707 回答