C ++ #define LPWSTR?

时间:2017-06-16 08:31:29

标签: c++ const createfile lpwstr

好的,我的程序有问题。我之前提出过一个问题,但是没有人真正理解我的问题,所以我这次尝试一种新方法。

如果您有点好奇这就是我的问题:

  

我的程序以char* argv[]的形式接受参数,并且我无法使用argv[1]指向LPWSTR上的任何内容,因为它只指向const wchar_t*对象。

这是我试图解决我的问题的新事物(我已经尝试了多项事情,但我需要知道如何做我的想法,或者是否可能)

基本上,我的想法是#define使用argv[1]上的任何内容的某种函数,并使用该值定义const wchar_t*

这样的事情:

#define path       ((const wchar_t*)argv[1])

我不确定这是正确的方式(或者即使这是可能的)来做我想做的事情......

如果你有更好的方法解决我的问题,请(请)告诉我如何帮助我,我一直在考虑这个很长的时间!

我的计划说明:

  

我正在制作一个接收争论的程序。参数是驱动器的名称,例如" F:"。然后它使用函数CreateFile和驱动器号。如果你去here,看到函数的第一个参数,我想你会看到我的意思....问题是,对于我来说,制作一个LPWSTR,我需要一个const wchat_t *对象。 ......我希望这次我的问题很清楚,上次人们并没有真正理解我想要做的事情。

无论如何,谢谢! 编辑1:这里是解决我的程序的行(这是我必须做的工作,没有参数)(我在这里使用固定值)

int main()
{

HANDLE device;

device = CreateFile(L"\\\\.\\F:",    // Drive to open
    GENERIC_READ | GENERIC_WRITE,       // Access mode
    FILE_SHARE_READ | FILE_SHARE_WRITE, // Share Mode
    NULL,                   // Security Descriptor
    OPEN_EXISTING,          // How to create
    0,                      // File attributes
    NULL);  
}

这是有争论的(没有工作)

int main(int argc, char* argv[])
{

HANDLE device;

device = CreateFile(argv[1],    // Drive to open
    GENERIC_READ | GENERIC_WRITE,       // Access mode
    FILE_SHARE_READ | FILE_SHARE_WRITE, // Share Mode
    NULL,                   // Security Descriptor
    OPEN_EXISTING,          // How to create
    0,                      // File attributes
    NULL);                  // Handle to template
}

^这显示我正在尝试做什么

编辑2:我将CreateFile更改为CreateFileA,这是它给我的eroor代码(驱动器D是usb,它不是硬盘) erros

因此,除非我输入错误的方式键入路径,否则它总是给我错误。我认为生病尝试另一种方法来解决问题,或者如果有人知道为什么会发生错误,请告诉我们!

1 个答案:

答案 0 :(得分:7)

  

编辑2:我将CreateFile更改为CreateFileA,这是它给我的eroor代码(驱动器D是usb,它不是硬盘)

这是一个完全不同的问题,与wchar_t无关。

在你的第一个剪辑中,你通过了"\\\\.\\F:"(AKA \\.\F:,一旦我们删除了C逃逸);在您从命令行尝试的所有尝试中,您从未提供此路径,但分别为:

  • D - 所以它试图在当前目录中打开一个名为D的文件,但它找不到它(错误2,又名ERROR_FILE_NOT_FOUND);
  • D:\ - 根目录,无法使用CreateFile打开(错误3,又名ERROR_PATH_NOT_FOUND),
  • D: - 驱动器D:上的当前目录,再次无法使用CreateFile打开(错误5,又名ERROR_ACCESS_DENIED);
  • \D: - 一个名为" D:"在当前驱动器的根目录中,由于D:不是有效的文件名(错误123,又名ERROR_INVALID_NAME),因此无法创建。

要将驱动器作为设备打开,必须使用\\.\X:路径(其中X是驱动器号);你不能只是抛出你心中的任何花车,并希望它能够发挥作用。从通过"\\.\D:"的命令行调用您的程序,它将正常工作。

当然,如果您想让用户更简单,您可以只接受命令行中的驱动器号,并编写一些代码以基于它创建CreateFile所需的字符串。

if(argc<1) {
    printf("Not enough arguments\n");
    return 1;
}
const char *drive = argv[1];
char d = drive[0];
// accept both `d` and `d:` as argument for the drive
if(!((d>='a' && d<='z') || (d>='A' && d<='Z')) ||
     (drive[1]!=0 && drive[1]!=':') ||
      drive[2]!=0) {
    printf("Invalid drive specifier: `%s`\n", drive);
    return 2;
}
char path[]="\\\\.\\X:";
path[4] = d;
// now you can use path as argument to CreateFileA

以下是原始答案,该答案仍然有效,但它解决了一个完全不同的问题,与OP遇到的实际问题无关

你不能通过粗暴地施放指针使LPWSTR指向char *,尤其是而不是 - 投射指针只会让编译器闭嘴,它不会“改变你所指的是而不是一个wchar_t字符串的事实。如果您想将char *传递给期望wchar_t *的函数,则必须执行指向数据的实际转换。

现在,您有几种可能的解决方案:

  • 您可以使用_wmain并直接接收命令行参数作为宽字符;
  • 您可以使用MultiByteToWideChar之类的函数将本地编码字符串转换为UTF-16字符串;这可以封装在返回std::wstring;
  • 的函数中
  • 您可以调用API的ANSI版本并让它处理它;几乎所有的Win32 API都有ANSI和Unicode版本,后缀为A和W(CreateFile只是一个扩展到CreateFileACreateFileW的宏,具体取决于_UNICODE宏)。因此,您可以使用CreateFileA并按原样传递字符串。

最后两个解决方案并不是很好,因为使用本地编码字符串作为命令行参数会阻止程序使用任意Unicode字符打开文件。 OTOH,使用wchar_t几乎无处不在,因为他们感染了#34;几乎应用程序的每个字符串处理角落。正确的(恕我直言)出路是在任何地方使用UTF-8,并在与操作系统交谈时动态转换; see here for details