【问题标题】:C++ #define LPWSTR?C++ #define LPWSTR?
【发布时间】:2017-06-16 08:31:28
【问题描述】:

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

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

我的程序接受 char* argv[] 形式的参数,我无法使用 LPWSTR 指向 argv[1] 上的任何内容,因为它只指向 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,它不是硬盘驱动器)

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

【问题讨论】:

  • 你能发布一些你的程序的代码吗?我认为这只是您的主要功能的前几行。
  • @kennyzx 当然,编辑不好
  • 也许宏不是最好的方法stackoverflow.com/questions/14041453/…

标签: c++ constants createfile lpwstr


【解决方案1】:

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

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

在您的第一个片段中,您通过了"\\\\.\\F:"(也就是我们删除 C 转义后的 \\.\F:);在您从命令行进行的所有尝试中,您从未提供过此路径,但分别:

  • 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 *,尤其是不能通过粗暴地转换指针——转换指针只会让编译器闭嘴,它不会改变什么你指向的是 not wchar_t 字符串。如果您想将 char * 传递给期望 wchar_t * 的函数,则必须对指向的数据执行实际转换。

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

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

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

【讨论】:

  • 我不明白如果我这样做 = int _wmain(int argc, char* argv[]),它不会仍然保存参数有 char* 吗?
  • 否,因为 _wmain 有不同的声明 (int _wmain(int argc, wchar_t *argv[]))。但是您在这里遇到的问题与此无关。让我编辑我的答案。
  • 拜托,我真的很想了解我的问题。
  • 已更新;下次请从一开始就说明您遇到的实际问题是什么。
  • 伙计,你不知道我在解决这个问题后花了多少时间,你真的只是节省了我的成绩,你能给我关于你的联系信息(姓名或昵称),这样我就可以把它放在我的项目报告? (如果你只想要ofcoure):-)而且我以前想真正理解我的问题,现在我明白了,真的很感激人
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-06
  • 2011-11-08
  • 1970-01-01
  • 2015-01-05
相关资源
最近更新 更多