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
只是一个扩展为 CreateFileA
或 CreateFileW
的宏,具体取决于 _UNICODE
宏)。因此,您可以使用 CreateFileA
并按原样将字符串传递给它。
最后两个解决方案不是很好,因为使用本地编码字符串作为命令行参数会阻止您的程序使用任意 Unicode 字符打开文件。 OTOH,几乎在任何地方都使用 wchar_t
是一件非常可怕的事情,因为它们 "infect" 几乎是应用程序的每个字符串处理角落。正确的(恕我直言)出路是在任何地方都使用 UTF-8,并在与操作系统对话时即时转换; see here for details.
好的,我的程序有问题。我之前提过一个问题,但是没有人真正理解我的问题,所以这次我尝试一种新的方法。
如果你好奇,这是我的问题:
My program takes arguments in the form of
char* argv[]
, and im having trouble making a pointer to whatever is onargv[1]
usingLPWSTR
, since it only point toconst 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
只是一个扩展为CreateFileA
或CreateFileW
的宏,具体取决于_UNICODE
宏)。因此,您可以使用CreateFileA
并按原样将字符串传递给它。
最后两个解决方案不是很好,因为使用本地编码字符串作为命令行参数会阻止您的程序使用任意 Unicode 字符打开文件。 OTOH,几乎在任何地方都使用 wchar_t
是一件非常可怕的事情,因为它们 "infect" 几乎是应用程序的每个字符串处理角落。正确的(恕我直言)出路是在任何地方都使用 UTF-8,并在与操作系统对话时即时转换; see here for details.