C++ #define LPWSTR?

C++ #define LPWSTR?

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

如果你好奇,这是我的问题:

My program takes arguments in the form of char* argv[] , and im having trouble making a pointer to whatever is on argv[1] using LPWSTR, since it only point to const wchar_t* objects.

这是我正在尝试解决我的问题的新事物(我尝试了多种方法,但我需要知道如何按照我的想法去做,或者如果可能的话)

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

像这样:

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

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

如果你有任何更好的方法来解决我的问题,请(请)告诉我如何解决并帮助我,我已经考虑了很长时间了!

我的程序说明:

Im making a program that recieves arguments. The arguments are the name of the drives, for example "F:". It then uses the function CreateFile with the drive letter. If you go here , and see the first parameter of the function, i think you will see what i mean.... the problem is that for me to make a LPWSTR, i would need a const wchat_t* object.... I hope my question is clear this time, last time people didnt really understand what i was trying to do.

无论如何,谢谢! 编辑 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 ,这是它给我的错误代码(驱动器 D 是 USB,不是硬盘)

所以除非我以错误的方式输入路径,否则它总是给我错误。我想我会尝试另一种方法来解决问题,或者如果有人知道为什么会出现这些错误,请告诉!

EDIT 2: i changed the CreateFile to CreateFileA , and this is the eroor codes it gives me (the drive D is a usb, its not a hard drive)

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

在您的第一个片段中,您通过了 "\\.\F:"(也就是 \.\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 是一件非常可怕的事情,因为它们 "infect" 几乎是应用程序的每个字符串处理角落。正确的(恕我直言)出路是在任何地方都使用 UTF-8,并在与操作系统对话时即时转换; see here for details.