Aas*_*ute 1 c++ string winapi visual-c++
我有一个功能,需要两个CHAR*作为输入即.int _stdcall FileTrans(char* InFile, char* OutFile)在DLL项目中.
在函数中我只是CopyFile(InFile, OutFile, false);在一些进程后调用(与文件无关).但它说它需要两个输入LPCWSTR.我用谷歌搜索它但找不到任何有趣的东西.
与所有接受字符串参数的Windows API函数一样,CopyFile函数实际上有两种变体:
CopyFileA是ANSI版本,它采用系统默认字符集中的窄(非Unicode)字符串.基本上,它接受类型的参数const char*,但Windows标头使用typedef LPCSTR.
CopyFileW是宽版本,它采用Unicode字符串.为了做到这一点,它接受类型的参数w_char*,但Windows标头使用typedef LPCWSTR(注意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);
Run Code Online (Sandbox Code Playgroud)
回想一下,您在上面学到的LPCWSTR只是一个typedef同义词const wchar_t*,一个由宽字符组成的C风格字符串.您已经知道为什么标记参数const:因为该函数不会修改这些值.
并且因为您还在上面已经了解到这些是您应该再使用的唯一类型的字符串,下一步是修改您的FileTrans函数以接受宽字符串(const如果它不会修改它们,则创建它们):
int _stdcall FileTrans(const wchar_t* InFile, const wchar_t* OutFile);
Run Code Online (Sandbox Code Playgroud)
现在,从FileTrans内部,您可以毫无问题地调用CopyFile,因为您拥有正确类型的字符串.
但是有点免费,额外的建议:永远不要在C++中使用原始C风格的字符串.始终使用标头在std命名空间中定义的C++字符串类<string>.
这个类有两种常见的变体,std::string和std::wstring.和以前一样,w指的是宽字符串,它是您要在Windows中使用的唯一类型.这std::wstring是您CHAR*在整个代码库中的新替代品.
将FileTrans函数的声明更改为如下所示:
#include <string>
// ...some other stuff...
int __stdcall FileTrans(const std::wstring& InFile, const std::wstring& OutFile);
Run Code Online (Sandbox Code Playgroud)
请注意,我已将原始CHAR*参数更改为对std::wstring对象的常量引用.常量引用在这里运行良好,因为您不会在函数内部更改这些值中的任何一个.
如果您不清楚常量是什么意思,如何使用引用,或者类类型通常如何在C++中工作,请参阅您最喜欢的C++书籍 - 这是所有C++程序员所必需的知识.请记住,C++与C语言不同,因此不适用相同的习语.在许多情况下,有一种更好的方法可以做,这肯定是这种情况的一个例子.
| 归档时间: |
|
| 查看次数: |
7497 次 |
| 最近记录: |